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 2020/08/01 16:00:32 UTC

[plc4x] 02/03: - Adjusted the existing mspec files to the changes in the code-generation (Explicitly Forwarded parent parser arguments to the children, where needed) - Worked a lot on the AMS/ADS mspec

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

commit 83762471fd7213ac8d6067b8e54f64bd18c2e46c
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Sat Aug 1 17:59:03 2020 +0200

    - Adjusted the existing mspec files to the changes in the code-generation (Explicitly Forwarded parent parser arguments to the children, where needed)
    - Worked a lot on the AMS/ADS mspec
---
 .../s7/readwrite/protocol/S7ProtocolLogic.java     |   2 +-
 .../main/resources/protocols/abeth/ab-eth.mspec    |   2 +-
 .../protocols/amsads/amsads-discovery.mspec        |  56 ++++++++
 .../main/resources/protocols/amsads/amsads.mspec   | 146 +++++++++++++--------
 .../resources/protocols/bacnetip/bacnetip.mspec    |  14 +-
 .../eip/src/main/resources/protocols/eip/eip.mspec |   6 +-
 .../main/resources/protocols/firmata/firmata.mspec |   4 +-
 .../s7/src/main/resources/protocols/s7/s7.mspec    |  10 +-
 8 files changed, 166 insertions(+), 74 deletions(-)

diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
index f99b5ed..420ddb2 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
@@ -221,7 +221,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
         return toPlcReadResponse((InternalPlcReadRequest) readRequest, readInternal(s7MessageRequest));
     }
 
-    /** Maps the S7ReadResponse of a PlcReadRequest to a PlcReadRespoonse */
+    /** Maps the S7ReadResponse of a PlcReadRequest to a PlcReadResponse */
     private CompletableFuture<PlcReadResponse> toPlcReadResponse(InternalPlcReadRequest readRequest, CompletableFuture<S7MessageResponseData> response) {
         return response
             .thenApply(p -> {
diff --git a/protocols/ab-eth/src/main/resources/protocols/abeth/ab-eth.mspec b/protocols/ab-eth/src/main/resources/protocols/abeth/ab-eth.mspec
index 851a072..5d8d0ff 100644
--- a/protocols/ab-eth/src/main/resources/protocols/abeth/ab-eth.mspec
+++ b/protocols/ab-eth/src/main/resources/protocols/abeth/ab-eth.mspec
@@ -62,7 +62,7 @@
     [simple        uint 8  'status']
     [simple        uint 16 'transactionCounter']
     [typeSwitch 'commandCode'
-        ['0x4F' DF1CommandResponseMessageProtectedTypedLogicalRead [uint 8 'status']
+        ['0x4F' DF1CommandResponseMessageProtectedTypedLogicalRead [uint 16 'payloadLength', uint 8 'status']
             [array    uint 8 'data' length 'payloadLength - 8']
         ]
     ]
diff --git a/protocols/amsads/src/main/resources/protocols/amsads/amsads-discovery.mspec b/protocols/amsads/src/main/resources/protocols/amsads/amsads-discovery.mspec
new file mode 100644
index 0000000..f549d70
--- /dev/null
+++ b/protocols/amsads/src/main/resources/protocols/amsads/amsads-discovery.mspec
@@ -0,0 +1,56 @@
+//
+// 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.
+//
+
+////////////////////////////////////////////////////////////////
+// AMS/TCP Packet
+////////////////////////////////////////////////////////////////
+
+[type 'AmsTCPDiscoveryPacket'
+    [const uint 32 'header' '0x03661471']
+    [reserved   uint 32  '0x00000000']
+    [simple     uint 16  'something']
+    [reserved   uint 16  '0x0000']
+    [simple     AmsNetId 'amsNetId']
+    [reserved   uint 16  '0x1027']
+    [simple     uint 16  'something2']
+    [reserved   uint 32  '0x0000']
+    [simple     uint 16  'something3']
+    [implicit   uint 16  'hostnameLength' 'COUNT(hostname)']
+    [array      int 8    'hostname' COUNT 'hostnameLength']
+    [reserved   uint 16  '0x4000']
+    [simple     uint 16  'something4']
+    [simple     uint 16  'something5']
+    [reserved   uint 32  '0x0000']
+    [simple     uint 16  'something6']
+    [reserved   uint 32  '0x0000']
+    [reserved   uint 32  '0x00000000']
+    [reserved   uint 32  '0x00000000']
+    [reserved   uint 16  '0x0000']
+    [implicit   uint 16  'ipLength' 'COUNT(ip)']
+    [array      int 8    'ip' COUNT 'ipLength']
+]
+
+[type 'AmsNetId'
+    [simple     uint        8   'octet1'            ]
+    [simple     uint        8   'octet2'            ]
+    [simple     uint        8   'octet3'            ]
+    [simple     uint        8   'octet4'            ]
+    [simple     uint        8   'octet5'            ]
+    [simple     uint        8   'octet6'            ]
+]
diff --git a/protocols/amsads/src/main/resources/protocols/amsads/amsads.mspec b/protocols/amsads/src/main/resources/protocols/amsads/amsads.mspec
index 0319554..e5131f4 100644
--- a/protocols/amsads/src/main/resources/protocols/amsads/amsads.mspec
+++ b/protocols/amsads/src/main/resources/protocols/amsads/amsads.mspec
@@ -22,19 +22,14 @@
 ////////////////////////////////////////////////////////////////
 
 [type 'AmsTCPPacket'
-    // The ams - tcp to be sent.
-    [simple AmsTcpHeader 'amsTcpHeader']
-    // The AMS packet to be sent.
-    [simple AmsPacket    'userdata'    ]
-]
-
-// AMS/TCP Header	6 bytes	contains the tcpLength of the data packet.
-[type 'AmsTcpHeader'
+    // AMS/TCP Header	6 bytes	contains the tcpLength of the data packet.
     // These bytes must be set to 0.
-    [reserved   uint       16       '0x0000' ]
+    [reserved   uint       16       '0x0000'                            ]
     // This array contains the length of the data packet.
     // It consists of the AMS-Header and the enclosed ADS data. The unit is bytes.
-    [simple     uint       32       'length']
+    [implicit   uint       32       'length'  'userdata.lengthInBytes'  ]
+    // The AMS packet to be sent.
+    [simple AmsPacket    'userdata'                                     ]
 ]
 
 ////////////////////////////////////////////////////////////////
@@ -59,7 +54,7 @@
     [simple     int          8  'fragmentNumber'     ]
     // The max. length of the AMS packet to be sent is 255. If larger AMS packets are to be sent then they have to be
     // fragmented (not published at the moment).
-    [simple     int          8  'length'     ]
+    [simple     int          8  'length'             ]
     [simple     uint        16  'crc'                ]
 ]
 
@@ -85,7 +80,7 @@
     [simple     int          8  'fragmentNumber'     ]
     // The max. length of the AMS packet to be sent is 255. If larger AMS packets are to be sent then they have to be
     // fragmented (not published at the moment).
-    [simple     int          8  'length'     ]
+    [simple     int          8  'length'             ]
     // The AMS packet to be sent.
     [simple AmsPacket           'userdata'           ]
     [simple     uint        16  'crc'                ]
@@ -117,12 +112,7 @@
 ////////////////////////////////////////////////////////////////
 
 [type 'AmsPacket'
-    [simple     AmsHeader  'amsHeader'                                                            ]
-    [simple     ADSData    'data'   ['amsHeader.commandId', 'amsHeader.state.response']              ]
-]
-
-// AMS Header	32 bytes	The AMS/TCP-Header contains the addresses of the transmitter and receiver. In addition the AMS error code , the ADS command Id and some other information.
-[type 'AmsHeader'
+    // AMS Header	32 bytes	The AMS/TCP-Header contains the addresses of the transmitter and receiver. In addition the AMS error code , the ADS command Id and some other information.
     // This is the AmsNetId of the station, for which the packet is intended. Remarks see below.
     [simple     AmsNetId        'targetAmsNetId'                            ]
     // This is the AmsPort of the station, for which the packet is intended.
@@ -136,12 +126,14 @@
     // 2 bytes.
     [simple     State           'state'                                     ]
     // 4 bytes	Size of the data range. The unit is byte.
-    [simple     uint        32  'length'                                ]
+    [implicit   uint        32  'length'   'data.lengthInBytes'             ]
     // 4 bytes	AMS error number. See ADS Return Codes.
     [simple     uint        32  'errorCode'                                 ]
     // free usable field of 4 bytes
     // 4 bytes	Free usable 32 bit array. Usually this array serves to send an Id. This Id makes is possible to assign a received response to a request, which was sent before.
     [simple      uint        32  'invokeId'                                 ]
+    // The payload
+    [simple     AdsData    'data'   ['commandId', 'state.response']         ]
 ]
 
 [enum uint 16 'CommandId'
@@ -158,8 +150,6 @@
 ]
 
 [type 'State'
-    [simple     bit 'broadcast'             ]
-    [reserved   int 7 '0x0'                 ]
     [simple     bit 'initCommand'           ]
     [simple     bit 'updCommand'            ]
     [simple     bit 'timestampAdded'        ]
@@ -168,6 +158,8 @@
     [simple     bit 'adsCommand'            ]
     [simple     bit 'noReturn'              ]
     [simple     bit 'response'              ]
+    [simple     bit 'broadcast'             ]
+    [reserved   int 7 '0x0'                 ]
 ]
 
 // It is not only possible to exchange data between TwinCAT modules on one PC, it is even possible to do so by ADS
@@ -198,10 +190,12 @@
     [simple     uint        8   'octet6'            ]
 ]
 
-[discriminatedType 'ADSData' [CommandId 'commandId', bit 'response']
+[discriminatedType 'AdsData' [CommandId 'commandId', bit 'response']
     [typeSwitch 'commandId', 'response'
-        ['CommandId.INVALID', 'true' AdsInvalidResponse]
         ['CommandId.INVALID', 'false' AdsInvalidRequest]
+        ['CommandId.INVALID', 'true' AdsInvalidResponse]
+
+        ['CommandId.ADS_READ_DEVICE_INFO', 'false' AdsReadDeviceInfoRequest]
         ['CommandId.ADS_READ_DEVICE_INFO', 'true' AdsReadDeviceInfoResponse
             // 4 bytes	ADS error number.
             [simple uint 32 'result']
@@ -214,15 +208,7 @@
             // Name	16 bytes	Name of ADS device
             [array int 8  'device' count '16']
         ]
-        ['CommandId.ADS_READ_DEVICE_INFO', 'false' AdsReadDeviceInfoRequest]
-        ['CommandId.ADS_READ', 'true' AdsReadResponse
-            // 4 bytes	ADS error number
-            [simple uint 32 'result']
-            // 4 bytes	Length of data which are supplied back.
-            [simple uint 32 'length']
-            // n bytes	Data which are supplied back.
-            [array int 8 'data' count 'length']
-        ]
+
         ['CommandId.ADS_READ', 'false' AdsReadRequest
             // 4 bytes	Index Group of the data which should be read.
             [simple uint 32 'indexGroup']
@@ -231,20 +217,31 @@
             // 4 bytes	Length of the data (in bytes) which should be read.
             [simple uint 32 'length']
         ]
-        ['CommandId.ADS_WRITE', 'true' AdsWriteResponse
+        ['CommandId.ADS_READ', 'true' AdsReadResponse
             // 4 bytes	ADS error number
             [simple uint 32 'result']
+            // 4 bytes	Length of data which are supplied back.
+            [implicit uint 32 'length' 'COUNT(data)']
+            // n bytes	Data which are supplied back.
+            [array int 8 'data' count 'length']
         ]
+
         ['CommandId.ADS_WRITE', 'false' AdsWriteRequest
             // 4 bytes	Index Group of the data which should be written.
             [simple uint 32 'indexGroup']
             // 4 bytes	Index Offset of the data which should be written.
             [simple uint 32 'indexOffset']
             // 4 bytes	Length of the data (in bytes) which should be written.
-            [simple uint 32 'length']
+            [implicit uint 32 'length' 'COUNT(data)']
             // n bytes	Data which are written in the ADS device.
             [array int 8 'data' count 'length']
         ]
+        ['CommandId.ADS_WRITE', 'true' AdsWriteResponse
+            // 4 bytes	ADS error number
+            [simple uint 32 'result']
+        ]
+
+        ['CommandId.ADS_READ_STATE', 'false' AdsReadStateRequest]
         ['CommandId.ADS_READ_STATE', 'true' AdsReadStateResponse
             // 4 bytes	ADS error number
             [simple uint 32 'result']
@@ -253,27 +250,22 @@
             // 2 bytes	New device status.
             [simple uint 16 'deviceState']
         ]
-        ['CommandId.ADS_READ_STATE', 'false' AdsReadStateRequest]
-        ['CommandId.ADS_WRITE_CONTROL', 'true' AdsWriteControlResponse
-            // 4 bytes	ADS error number
-            [simple uint 32 'result']
-        ]
+
         ['CommandId.ADS_WRITE_CONTROL', 'false' AdsWriteControlRequest
             // 2 bytes	New ADS status (see data type ADSSTATE of the ADS-DLL).
             [simple uint 16 'adsState']
             // 2 bytes	New device status.
             [simple uint 16 'deviceState']
             // 4 bytes	Length of data in byte.
-            [simple uint 32 'length']
+            [implicit uint 32 'length' 'COUNT(data)']
             // n bytes	Additional data which are sent to the ADS device
             [array int 8 'data' count 'length']
         ]
-        ['CommandId.ADS_ADD_DEVICE_NOTIFICATION', 'true' AdsAddDeviceNotificationResponse
+        ['CommandId.ADS_WRITE_CONTROL', 'true' AdsWriteControlResponse
             // 4 bytes	ADS error number
             [simple uint 32 'result']
-            // 4 bytes	Handle of notification
-            [simple uint 32 'notificationHandle']
         ]
+
         ['CommandId.ADS_ADD_DEVICE_NOTIFICATION', 'false' AdsAddDeviceNotificationRequest
             // 4 bytes	Index Group of the data, which should be sent per notification.
             [simple uint 32 'indexGroup']
@@ -291,15 +283,22 @@
             // 16bytes	Must be set to 0
             [reserved   uint       128       '0x0000' ]
         ]
-        ['CommandId.ADS_DELETE_DEVICE_NOTIFICATION', 'true' AdsDeleteDeviceNotificationResponse
+        ['CommandId.ADS_ADD_DEVICE_NOTIFICATION', 'true' AdsAddDeviceNotificationResponse
             // 4 bytes	ADS error number
             [simple uint 32 'result']
+            // 4 bytes	Handle of notification
+            [simple uint 32 'notificationHandle']
         ]
+
         ['CommandId.ADS_DELETE_DEVICE_NOTIFICATION', 'false' AdsDeleteDeviceNotificationRequest
             // 4 bytes	Handle of notification
             [simple uint 32 'notificationHandle']
         ]
-        ['CommandId.ADS_DEVICE_NOTIFICATION', 'true' AdsDeviceNotificationResponse]
+        ['CommandId.ADS_DELETE_DEVICE_NOTIFICATION', 'true' AdsDeleteDeviceNotificationResponse
+            // 4 bytes	ADS error number
+            [simple uint 32 'result']
+        ]
+
         ['CommandId.ADS_DEVICE_NOTIFICATION', 'false' AdsDeviceNotificationRequest
             // 4 bytes	Size of data in byte.
             [simple uint 32 'length']
@@ -308,14 +307,8 @@
             // n bytes	Array with elements of type AdsStampHeader.
             [array AdsStampHeader 'adsStampHeaders' count 'stamps']
         ]
-        ['CommandId.ADS_READ_WRITE', 'true' AdsReadWriteResponse
-            // 4 bytes	ADS error number
-            [simple uint 32 'result']
-            // 4 bytes	Length of data in byte.
-            [simple uint 32 'length']
-            // n bytes	Additional data which are sent to the ADS device
-            [array int 8 'data' count 'length']
-        ]
+        ['CommandId.ADS_DEVICE_NOTIFICATION', 'true' AdsDeviceNotificationResponse]
+
         ['CommandId.ADS_READ_WRITE', 'false' AdsReadWriteRequest
             // 4 bytes	Index Group of the data which should be written.
             [simple uint 32 'indexGroup']
@@ -324,9 +317,19 @@
             // 4 bytes	Length of data in bytes, which should be read.
             [simple uint 32 'readLength']
             // 4 bytes	Length of the data (in bytes) which should be written.
-            [simple uint 32 'writeLength']
+            [implicit uint 32 'writeLength' '(COUNT(items) * 12) + COUNT(data)']
+            // Only if the indexGroup implies a sum-read response, will the indexOffset indicate the number of elements.
+            [array  AdsReadRequest 'items' COUNT '(indexGroup == ReservedIndexGroups.ADSIGRP_MULTIPLE_READ.value) ? indexOffset : 0']
             // n bytes	Data which are written in the ADS device.
-            [array int 8 'data' count 'writeLength']
+            [array int 8 'data' count 'writeLength - (COUNT(items) * 12)']
+        ]
+        ['CommandId.ADS_READ_WRITE', 'true' AdsReadWriteResponse
+            // 4 bytes	ADS error number
+            [simple uint 32 'result']
+            // 4 bytes	Length of data in byte.
+            [implicit uint 32 'length'  'COUNT(data)']
+            // n bytes Additional data which are sent to the ADS device
+            [array int 8 'data' count 'length']
         ]
     ]
 ]
@@ -347,4 +350,37 @@
     [simple uint 32 'sampleSize']
     // n Bytes	Data
     [array int 8 'data' count 'sampleSize']
+]
+
+[enum uint 16 'ReservedIndexGroups'
+    ['0xF000' ADSIGRP_SYMTAB]
+    ['0xF001' ADSIGRP_SYMNAME]
+    ['0xF002' ADSIGRP_SYMVAL]
+    ['0xF003' ADSIGRP_SYM_HNDBYNAME]
+    ['0xF004' ADSIGRP_SYM_VALBYNAME]
+    ['0xF005' ADSIGRP_SYM_VALBYHND]
+    ['0xF006' ADSIGRP_SYM_RELEASEHND]
+    ['0xF007' ADSIGRP_SYM_INFOBYNAME]
+    ['0xF008' ADSIGRP_SYM_VERSION]
+    ['0xF009' ADSIGRP_SYM_INFOBYNAMEEX]
+    ['0xF00A' ADSIGRP_SYM_DOWNLOAD]
+    ['0xF00B' ADSIGRP_SYM_UPLOAD]
+    ['0xF00C' ADSIGRP_SYM_UPLOADINFO]
+    ['0xF010' ADSIGRP_SYMNOTE]
+    ['0xF020' ADSIGRP_IOIMAGE_RWIB]
+    ['0xF021' ADSIGRP_IOIMAGE_RWIX]
+    ['0xF025' ADSIGRP_IOIMAGE_RISIZE]
+    ['0xF030' ADSIGRP_IOIMAGE_RWOB]
+    ['0xF031' ADSIGRP_IOIMAGE_RWOX]
+    ['0xF035' ADSIGRP_IOIMAGE_RWOSIZE]
+    ['0xF040' ADSIGRP_IOIMAGE_CLEARI]
+    ['0xF050' ADSIGRP_IOIMAGE_CLEARO]
+    ['0xF060' ADSIGRP_IOIMAGE_RWIOB]
+    ['0xF080' ADSIGRP_MULTIPLE_READ]
+    ['0xF081' ADSIGRP_MULTIPLE_WRITE]
+    ['0xF082' ADSIGRP_MULTIPLE_GET_HANDLE]
+    ['0xF083' ADSIGRP_MULTIPLE_RELEASE_HANDLE]
+    ['0xF100' ADSIGRP_DEVICE_DATA]
+    ['0x0000' ADSIOFFS_DEVDATA_ADSSTATE]
+    ['0x0002' ADSIOFFS_DEVDATA_DEVSTATE]
 ]
\ No newline at end of file
diff --git a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
index eb001e9..870fe12 100644
--- a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
+++ b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
@@ -80,10 +80,10 @@
     [discriminator uint 8  'messageType']
     [optional      uint 16 'vendorId' '(messageType >= 128) && (messageType <= 255)']
     [typeSwitch 'messageType'
-        ['0x0' NLMWhoIsRouterToNetwork [uint 8  'messageType']
+        ['0x0' NLMWhoIsRouterToNetwork [uint 16 'apduLength', uint 8  'messageType']
             [array uint 16 'destinationNetworkAddress' length 'apduLength - (((messageType >= 128) && (messageType <= 255)) ? 3 : 1)']
         ]
-        ['0x1' NLMIAmRouterToNetwork [uint 8  'messageType']
+        ['0x1' NLMIAmRouterToNetwork [uint 16 'apduLength', uint 8  'messageType']
             [array uint 16 'destinationNetworkAddress' length 'apduLength - (((messageType >= 128) && (messageType <= 255)) ? 3 : 1)']
         ]
     ]
@@ -92,7 +92,7 @@
 [discriminatedType 'APDU' [uint 16 'apduLength']
     [discriminator uint 4 'apduType']
     [typeSwitch 'apduType'
-        ['0x0' APDUConfirmedRequest
+        ['0x0' APDUConfirmedRequest [uint 16 'apduLength']
             [simple   bit    'segmentedMessage'                       ]
             [simple   bit    'moreFollows'                            ]
             [simple   bit    'segmentedResponseAccepted'              ]
@@ -104,7 +104,7 @@
             [optional uint 8 'proposedWindowSize'   'segmentedMessage']
             [simple   BACnetConfirmedServiceRequest 'serviceRequest'  ['apduLength - (3 + (segmentedMessage ? 2 : 0))']]
         ]
-        ['0x1' APDUUnconfirmedRequest
+        ['0x1' APDUUnconfirmedRequest [uint 16 'apduLength']
             [reserved uint 4                          '0'             ]
             [simple   BACnetUnconfirmedServiceRequest 'serviceRequest' ['apduLength - 1']]
         ]
@@ -154,7 +154,7 @@
     [typeSwitch 'serviceChoice'
         ['0x00' BACnetConfirmedServiceRequestAcknowledgeAlarm
         ]
-        ['0x01' BACnetConfirmedServiceRequestConfirmedCOVNotification
+        ['0x01' BACnetConfirmedServiceRequestConfirmedCOVNotification [uint 16 'len']
             [const  uint 8               'subscriberProcessIdentifierHeader'         '0x09'                 ]
             [simple uint 8               'subscriberProcessIdentifier'                                      ]
             [const  uint 8               'monitoredObjectIdentifierHeader'           '0x1C'                 ]
@@ -224,7 +224,7 @@
         ]
         ['0x1A' BACnetConfirmedServiceRequestReadRange
         ]
-        ['0x0F' BACnetConfirmedServiceRequestWriteProperty
+        ['0x0F' BACnetConfirmedServiceRequestWriteProperty [uint 16 'len']
             [const    uint 8    'objectIdentifierHeader'    '0x0C'                          ]
             [simple   uint 10   'objectType'                                                ]
             [simple   uint 22   'objectInstanceNumber'                                      ]
@@ -300,7 +300,7 @@
         ]
         ['0x03' BACnetUnconfirmedServiceRequestUnconfirmedEventNotification
         ]
-        ['0x04' BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer
+        ['0x04' BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer [uint 16 'len']
             [const uint 8 'vendorIdHeader' '0x09']
             [simple uint 8 'vendorId']
             [const uint 8 'serviceNumberHeader' '0x1A']
diff --git a/protocols/eip/src/main/resources/protocols/eip/eip.mspec b/protocols/eip/src/main/resources/protocols/eip/eip.mspec
index b772ff1..f375772 100644
--- a/protocols/eip/src/main/resources/protocols/eip/eip.mspec
+++ b/protocols/eip/src/main/resources/protocols/eip/eip.mspec
@@ -58,7 +58,7 @@
             [array      int     8   'tag'   length  '(RequestPathSize*2)']
             [simple     uint    16  'elementNb']
         ]
-        ['0xCC' CipReadResponse
+        ['0xCC' CipReadResponse [uint 16 'serviceLen']
               [reserved   uint            8   '0x00']
               [simple     uint            8   'status']
               [simple     uint            8   'extStatus']
@@ -77,12 +77,12 @@
             [simple     uint        8   'status']
             [simple     uint        8   'extStatus']
         ]
-        ['0x0A' MultipleServiceRequest
+        ['0x0A' MultipleServiceRequest [uint 16 'serviceLen']
                [const  int     8   'RequestPathSize'   '0x02']
                [const  uint    32  'RequestPath'       '0x01240220']   //Logical Segment: Class(0x20) 0x02, Instance(0x24) 01 (Message Router)
                [simple Services  'data'         ['serviceLen - 6 '] ]
         ]
-        ['0x8A' MultipleServiceResponse
+        ['0x8A' MultipleServiceResponse [uint 16 'serviceLen']
                [reserved   uint    8   '0x0']
                [simple     uint    8   'status']
                [simple     uint    8   'extStatus']
diff --git a/protocols/firmata/src/main/resources/protocols/firmata/firmata.mspec b/protocols/firmata/src/main/resources/protocols/firmata/firmata.mspec
index 20f88ad..17313db 100644
--- a/protocols/firmata/src/main/resources/protocols/firmata/firmata.mspec
+++ b/protocols/firmata/src/main/resources/protocols/firmata/firmata.mspec
@@ -50,7 +50,7 @@
         ]
 
         // Command
-        ['0xF' FirmataMessageCommand
+        ['0xF' FirmataMessageCommand [bit 'response']
             [simple FirmataCommand 'command' ['response']]
         ]
     ]
@@ -59,7 +59,7 @@
 [discriminatedType 'FirmataCommand' [bit 'response']
     [discriminator uint 4 'commandCode']
     [typeSwitch 'commandCode'
-        ['0x0' FirmataCommandSysex
+        ['0x0' FirmataCommandSysex [bit 'response']
             [simple SysexCommand 'command' ['response']]
             [reserved uint 8 '0xF7']
         ]
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index e428620..10fbb80 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -84,7 +84,7 @@
         ['0xC3' COTPParameterChecksum
             [simple uint 8 'crc']
         ]
-        ['0xE0' COTPParameterDisconnectAdditionalInformation
+        ['0xE0' COTPParameterDisconnectAdditionalInformation [uint 8 'rest']
             [array  uint 8 'data' count 'rest']
         ]
     ]
@@ -213,16 +213,16 @@
 
 [discriminatedType 'S7Payload' [uint 8 'messageType', S7Parameter 'parameter']
     [typeSwitch 'parameter.parameterType', 'messageType'
-        ['0x04','0x03' S7PayloadReadVarResponse
+        ['0x04','0x03' S7PayloadReadVarResponse [S7Parameter 'parameter']
             [array S7VarPayloadDataItem 'items' count 'CAST(parameter, S7ParameterReadVarResponse).numItems' ['lastItem']]
         ]
-        ['0x05','0x01' S7PayloadWriteVarRequest
+        ['0x05','0x01' S7PayloadWriteVarRequest [S7Parameter 'parameter']
             [array S7VarPayloadDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterWriteVarRequest).items)' ['lastItem']]
         ]
-        ['0x05','0x03' S7PayloadWriteVarResponse
+        ['0x05','0x03' S7PayloadWriteVarResponse [S7Parameter 'parameter']
             [array S7VarPayloadStatusItem 'items' count 'CAST(parameter, S7ParameterWriteVarResponse).numItems']
         ]
-        ['0x00','0x07' S7PayloadUserData
+        ['0x00','0x07' S7PayloadUserData [S7Parameter 'parameter']
             [array S7PayloadUserDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterUserData).items)' ['CAST(CAST(parameter, S7ParameterUserData).items[0], S7ParameterUserDataItemCPUFunctions).cpuFunctionType']]
         ]
     ]