You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2026/08/18 20:22:24 UTC
(plc4x) 06/17: fix(plc4go/eip): reconcile CIP value codecs with plc4j (arrays, REAL/LREAL/LINT/STRING, short-reply guard)
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 60149e3389d0a480b5fc6c962cf6a194262d7f07
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Aug 18 17:06:47 2026 +0200
fix(plc4go/eip): reconcile CIP value codecs with plc4j (arrays, REAL/LREAL/LINT/STRING, short-reply guard)
---
plc4go/internal/eip/Reader.go | 103 +-------------------
plc4go/internal/eip/TagHandler.go | 33 ++++++-
plc4go/internal/eip/Values.go | 188 +++++++++++++++++++++++++++++++++++++
plc4go/internal/eip/Values_test.go | 112 ++++++++++++++++++++++
plc4go/internal/eip/Writer.go | 34 +------
5 files changed, 334 insertions(+), 136 deletions(-)
diff --git a/plc4go/internal/eip/Reader.go b/plc4go/internal/eip/Reader.go
index 339e5b5389..5de3754072 100644
--- a/plc4go/internal/eip/Reader.go
+++ b/plc4go/internal/eip/Reader.go
@@ -40,7 +40,6 @@ import (
"github.com/apache/plc4x/plc4go/spi/options"
"github.com/apache/plc4x/plc4go/spi/transactions"
"github.com/apache/plc4x/plc4go/spi/utils"
- spiValues "github.com/apache/plc4x/plc4go/spi/values"
)
type Reader struct {
@@ -220,10 +219,9 @@ func (m *Reader) ToPlc4xReadResponse(response readWriteModel.CipService, readReq
code := decodeResponseCode(cipReadResponse.GetStatus())
var plcValue values.PlcValue
_type := cipReadResponse.GetData().GetDataType()
- data := utils.NewReadBufferByteBased(cipReadResponse.GetData().GetData(), utils.WithByteOrderForReadBufferByteBased(binary.LittleEndian))
if code == apiModel.PlcResponseCode_OK {
var err error
- plcValue, err = parsePlcValue(tag, data, _type)
+ plcValue, err = parsePlcValue(tag, cipReadResponse.GetData().GetData(), _type)
if err != nil {
return nil, err
}
@@ -258,11 +256,10 @@ func (m *Reader) ToPlc4xReadResponse(response readWriteModel.CipService, readReq
if cipReadResponse, ok := services.Services[i].(readWriteModel.CipReadResponse); ok {
code := decodeResponseCode(cipReadResponse.GetStatus())
_type := cipReadResponse.GetData().GetDataType()
- data := utils.NewReadBufferByteBased(cipReadResponse.GetData().GetData(), utils.WithByteOrderForReadBufferByteBased(binary.LittleEndian))
var plcValue values.PlcValue
if code == apiModel.PlcResponseCode_OK {
var err error
- plcValue, err = parsePlcValue(tag, data, _type)
+ plcValue, err = parsePlcValue(tag, cipReadResponse.GetData().GetData(), _type)
if err != nil {
return nil, err
}
@@ -282,99 +279,3 @@ func (m *Reader) ToPlc4xReadResponse(response readWriteModel.CipService, readReq
m.log.Trace().Msg("Returning the response")
return spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues), nil
}
-
-func parsePlcValue(tag PlcTag, data utils.ReadBufferByteBased, _type readWriteModel.CIPDataTypeCode) (values.PlcValue, error) {
- nb := tag.GetElementNb()
- if nb > 1 {
- list := make([]values.PlcValue, 0)
- for range nb {
- switch _type {
- case readWriteModel.CIPDataTypeCode_DINT:
- readInt32, err := data.ReadInt32("", _type.Size()*8)
- if err != nil {
- return nil, err
- }
- list = append(list, spiValues.NewPlcDINT(readInt32))
- case readWriteModel.CIPDataTypeCode_INT:
- readInt16, err := data.ReadInt16("", _type.Size()*8)
- if err != nil {
- return nil, err
- }
- list = append(list, spiValues.NewPlcINT(readInt16))
- case readWriteModel.CIPDataTypeCode_SINT:
- readInt8, err := data.ReadInt8("", _type.Size()*8)
- if err != nil {
- return nil, err
- }
- list = append(list, spiValues.NewPlcSINT(readInt8))
- case readWriteModel.CIPDataTypeCode_REAL:
- if _type.Size()*8 != 64 {
- return nil, errors.New("Unexpected size")
- }
- readFloat64, err := data.ReadFloat64("", 64)
- if err != nil {
- return nil, err
- }
- list = append(list, spiValues.NewPlcLREAL(readFloat64))
- case readWriteModel.CIPDataTypeCode_BOOL:
- bit, err := data.ReadBit("")
- if err != nil {
- return nil, err
- }
- list = append(list, spiValues.NewPlcBOOL(bit))
- default:
- return nil, errors.Errorf("Unknown type %v", _type)
- }
- }
- return spiValues.NewPlcList(list), nil
- } else {
- switch _type {
- case readWriteModel.CIPDataTypeCode_SINT:
- readByte, err := data.ReadInt8("", _type.Size()*8)
- if err != nil {
- return nil, err
- }
- return spiValues.NewPlcSINT(readByte), nil
- case readWriteModel.CIPDataTypeCode_INT:
- readInt16, err := data.ReadInt16("", _type.Size()*8)
- if err != nil {
- return nil, err
- }
- return spiValues.NewPlcINT(readInt16), nil
- case readWriteModel.CIPDataTypeCode_DINT:
- readInt32, err := data.ReadInt32("", _type.Size()*8)
- if err != nil {
- return nil, err
- }
- return spiValues.NewPlcDINT(readInt32), nil
- case readWriteModel.CIPDataTypeCode_REAL:
- if _type.Size()*8 != 64 {
- return nil, errors.New("Unexpected size")
- }
- readFloat32, err := data.ReadFloat32("", 64)
- if err != nil {
- return nil, err
- }
- return spiValues.NewPlcREAL(readFloat32), nil
- case readWriteModel.CIPDataTypeCode_BOOL:
- readBit, err := data.ReadBit("")
- if err != nil {
- return nil, err
- }
- return spiValues.NewPlcBOOL(readBit), nil
- default:
- return nil, errors.Errorf("Unknown type %v", _type)
- }
- }
-}
-
-// Helper to convert the return codes returned from the eip into one of our standard
-func decodeResponseCode(status uint8) apiModel.PlcResponseCode {
- //TODO other status
- switch status {
- case 0:
- return apiModel.PlcResponseCode_OK
- default:
- return apiModel.PlcResponseCode_INTERNAL_ERROR
- }
-}
diff --git a/plc4go/internal/eip/TagHandler.go b/plc4go/internal/eip/TagHandler.go
index 3013f07013..9b5bb999d9 100644
--- a/plc4go/internal/eip/TagHandler.go
+++ b/plc4go/internal/eip/TagHandler.go
@@ -22,6 +22,7 @@ package eip
import (
"fmt"
"regexp"
+ "strconv"
apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
"github.com/apache/plc4x/plc4go/protocols/eip/readwrite/model"
@@ -44,8 +45,36 @@ const (
)
func (m TagHandler) ParseTag(tagAddress string) (apiModel.PlcTag, error) {
- // TODO: This isn't pretty ...
- return NewTag(tagAddress, model.CIPDataTypeCode_DINT, uint16(1)), nil
+ matches := m.addressPattern.FindStringSubmatch(tagAddress)
+ if matches == nil {
+ return nil, fmt.Errorf("invalid tag address: %s", tagAddress)
+ }
+
+ tagName := matches[m.addressPattern.SubexpIndex(TAG)]
+ dataTypeStr := matches[m.addressPattern.SubexpIndex(DATA_TYPE)]
+ elementNbStr := matches[m.addressPattern.SubexpIndex(ELEMENT_NB)]
+
+ var dataType model.CIPDataTypeCode
+ if dataTypeStr == "" {
+ dataType = model.CIPDataTypeCode_DINT
+ } else {
+ var found bool
+ dataType, found = model.CIPDataTypeCodeByName(dataTypeStr)
+ if !found {
+ return nil, fmt.Errorf("unknown data type: %s", dataTypeStr)
+ }
+ }
+
+ elementNb := uint16(1)
+ if elementNbStr != "" {
+ nb, err := strconv.ParseUint(elementNbStr, 10, 16)
+ if err != nil {
+ return nil, fmt.Errorf("invalid element count: %s", elementNbStr)
+ }
+ elementNb = uint16(nb)
+ }
+
+ return NewTag(tagName, dataType, elementNb), nil
}
func (m TagHandler) ParseQuery(query string) (apiModel.PlcQuery, error) {
diff --git a/plc4go/internal/eip/Values.go b/plc4go/internal/eip/Values.go
new file mode 100644
index 0000000000..267f4fb1ee
--- /dev/null
+++ b/plc4go/internal/eip/Values.go
@@ -0,0 +1,188 @@
+/*
+ * 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
+ *
+ * https://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.
+ */
+
+package eip
+
+import (
+ "encoding/binary"
+ "math"
+
+ apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
+ "github.com/apache/plc4x/plc4go/pkg/api/values"
+ apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
+ readWriteModel "github.com/apache/plc4x/plc4go/protocols/eip/readwrite/model"
+ "github.com/apache/plc4x/plc4go/spi/errors"
+ spiValues "github.com/apache/plc4x/plc4go/spi/values"
+)
+
+const (
+ stringLenOffset = 2
+ stringDataOffset = 6
+)
+
+// elementCount is the number of elements to ask the device for. An array tag
+// has to request all of its elements (GH-1008) - otherwise the device returns
+// a single element and the decoder has nothing to read the rest from.
+func elementCount(tag PlcTag) uint16 {
+ if tag.GetElementNb() > 1 {
+ return tag.GetElementNb()
+ }
+ return 1
+}
+
+// isFixedSize reports whether the type is stored as a flat sequence of equally
+// sized elements.
+func isFixedSize(dataType readWriteModel.CIPDataTypeCode) bool {
+ switch dataType {
+ case readWriteModel.CIPDataTypeCode_SINT,
+ readWriteModel.CIPDataTypeCode_INT,
+ readWriteModel.CIPDataTypeCode_DINT,
+ readWriteModel.CIPDataTypeCode_LINT,
+ readWriteModel.CIPDataTypeCode_REAL,
+ readWriteModel.CIPDataTypeCode_LREAL,
+ readWriteModel.CIPDataTypeCode_BOOL:
+ return true
+ default:
+ return false
+ }
+}
+
+// parsePlcValue decodes a CIP read payload. CIP data is little-endian on the
+// wire regardless of the encapsulation byte order.
+func parsePlcValue(tag PlcTag, rawData []byte, dataType readWriteModel.CIPDataTypeCode) (values.PlcValue, error) {
+ nb := int(elementCount(tag))
+ elementSize := int(dataType.Size())
+ if isFixedSize(dataType) && len(rawData) < nb*elementSize {
+ // Never read past what the device actually sent - a short reply must not
+ // blow up the whole response.
+ return nil, errors.Errorf("device returned %d bytes for tag '%s', expected %d for %d element(s) of %s",
+ len(rawData), tag.GetTag(), nb*elementSize, nb, dataType)
+ }
+ if nb > 1 {
+ list := make([]values.PlcValue, 0, nb)
+ for i := 0; i < nb; i++ {
+ offset := i * elementSize
+ switch dataType {
+ case readWriteModel.CIPDataTypeCode_SINT:
+ list = append(list, spiValues.NewPlcSINT(int8(rawData[offset])))
+ case readWriteModel.CIPDataTypeCode_INT:
+ list = append(list, spiValues.NewPlcINT(int16(binary.LittleEndian.Uint16(rawData[offset:]))))
+ case readWriteModel.CIPDataTypeCode_DINT:
+ list = append(list, spiValues.NewPlcDINT(int32(binary.LittleEndian.Uint32(rawData[offset:]))))
+ case readWriteModel.CIPDataTypeCode_LINT:
+ list = append(list, spiValues.NewPlcLINT(int64(binary.LittleEndian.Uint64(rawData[offset:]))))
+ case readWriteModel.CIPDataTypeCode_REAL:
+ list = append(list, spiValues.NewPlcREAL(math.Float32frombits(binary.LittleEndian.Uint32(rawData[offset:]))))
+ case readWriteModel.CIPDataTypeCode_LREAL:
+ list = append(list, spiValues.NewPlcLREAL(math.Float64frombits(binary.LittleEndian.Uint64(rawData[offset:]))))
+ case readWriteModel.CIPDataTypeCode_BOOL:
+ list = append(list, spiValues.NewPlcBOOL(rawData[offset] != 0))
+ case readWriteModel.CIPDataTypeCode_STRING, readWriteModel.CIPDataTypeCode_STRUCTURED:
+ // STRING/STRUCTURED carry their own length; plc4j decodes a single
+ // string here and returns.
+ value, err := parseStructured(tag, rawData)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, value)
+ return spiValues.NewPlcList(list), nil
+ default:
+ return nil, errors.Errorf("unsupported type %s", dataType)
+ }
+ }
+ return spiValues.NewPlcList(list), nil
+ }
+ switch dataType {
+ case readWriteModel.CIPDataTypeCode_SINT:
+ return spiValues.NewPlcSINT(int8(rawData[0])), nil
+ case readWriteModel.CIPDataTypeCode_INT:
+ return spiValues.NewPlcINT(int16(binary.LittleEndian.Uint16(rawData))), nil
+ case readWriteModel.CIPDataTypeCode_DINT:
+ return spiValues.NewPlcDINT(int32(binary.LittleEndian.Uint32(rawData))), nil
+ case readWriteModel.CIPDataTypeCode_LINT:
+ return spiValues.NewPlcLINT(int64(binary.LittleEndian.Uint64(rawData))), nil
+ case readWriteModel.CIPDataTypeCode_REAL:
+ return spiValues.NewPlcREAL(math.Float32frombits(binary.LittleEndian.Uint32(rawData))), nil
+ case readWriteModel.CIPDataTypeCode_LREAL:
+ return spiValues.NewPlcLREAL(math.Float64frombits(binary.LittleEndian.Uint64(rawData))), nil
+ case readWriteModel.CIPDataTypeCode_BOOL:
+ return spiValues.NewPlcBOOL(rawData[0] != 0), nil
+ case readWriteModel.CIPDataTypeCode_STRING, readWriteModel.CIPDataTypeCode_STRUCTURED:
+ return parseStructured(tag, rawData)
+ default:
+ return nil, errors.Errorf("unsupported type %s", dataType)
+ }
+}
+
+func parseStructured(tag PlcTag, rawData []byte) (values.PlcValue, error) {
+ if len(rawData) < stringDataOffset {
+ return nil, errors.Errorf("structured payload for tag '%s' too short: %d bytes", tag.GetTag(), len(rawData))
+ }
+ structuredType := binary.LittleEndian.Uint16(rawData[0:])
+ structuredLen := int(binary.LittleEndian.Uint16(rawData[stringLenOffset:]))
+ if structuredType != uint16(readWriteModel.CIPStructTypeCode_STRING) {
+ return nil, errors.Errorf("unsupported structured type %#x for tag '%s'", structuredType, tag.GetTag())
+ }
+ if len(rawData) < stringDataOffset+structuredLen {
+ return nil, errors.Errorf("string payload for tag '%s' too short: %d bytes for length %d",
+ tag.GetTag(), len(rawData), structuredLen)
+ }
+ return spiValues.NewPlcSTRING(string(rawData[stringDataOffset : stringDataOffset+structuredLen])), nil
+}
+
+// encodeValue serializes a single value for a CIP write. Like plc4j it encodes
+// one element; array writes carry the element count in the CipWriteRequest.
+func encodeValue(value apiValues.PlcValue, dataType readWriteModel.CIPDataTypeCode) ([]byte, error) {
+ switch dataType {
+ case readWriteModel.CIPDataTypeCode_BOOL:
+ boolByte := byte(0)
+ if value.GetBool() {
+ boolByte = 1
+ }
+ return []byte{boolByte}, nil
+ case readWriteModel.CIPDataTypeCode_SINT:
+ return []byte{byte(value.GetInt8())}, nil
+ case readWriteModel.CIPDataTypeCode_INT:
+ return binary.LittleEndian.AppendUint16(nil, uint16(value.GetInt16())), nil
+ case readWriteModel.CIPDataTypeCode_DINT:
+ return binary.LittleEndian.AppendUint32(nil, uint32(value.GetInt32())), nil
+ case readWriteModel.CIPDataTypeCode_LINT:
+ return binary.LittleEndian.AppendUint64(nil, uint64(value.GetInt64())), nil
+ case readWriteModel.CIPDataTypeCode_REAL:
+ return binary.LittleEndian.AppendUint32(nil, math.Float32bits(value.GetFloat32())), nil
+ case readWriteModel.CIPDataTypeCode_LREAL:
+ return binary.LittleEndian.AppendUint64(nil, math.Float64bits(value.GetFloat64())), nil
+ case readWriteModel.CIPDataTypeCode_STRING, readWriteModel.CIPDataTypeCode_STRUCTURED:
+ text := value.GetString()
+ raw := binary.LittleEndian.AppendUint32(nil, uint32(len(text)))
+ return append(raw, text...), nil
+ default:
+ return nil, errors.Errorf("unsupported type %s", dataType)
+ }
+}
+
+// decodeResponseCode converts a CIP status into a PLC4X response code.
+func decodeResponseCode(status uint8) apiModel.PlcResponseCode {
+ switch status {
+ case 0:
+ return apiModel.PlcResponseCode_OK
+ default:
+ return apiModel.PlcResponseCode_INTERNAL_ERROR
+ }
+}
diff --git a/plc4go/internal/eip/Values_test.go b/plc4go/internal/eip/Values_test.go
new file mode 100644
index 0000000000..8d2e3f1307
--- /dev/null
+++ b/plc4go/internal/eip/Values_test.go
@@ -0,0 +1,112 @@
+/*
+ * 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
+ *
+ * https://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.
+ */
+
+package eip
+
+import (
+ "encoding/binary"
+ "math"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
+ readWriteModel "github.com/apache/plc4x/plc4go/protocols/eip/readwrite/model"
+ spiValues "github.com/apache/plc4x/plc4go/spi/values"
+)
+
+func mustTag(t *testing.T, address string) PlcTag {
+ tag, err := NewTagHandler().ParseTag(address)
+ require.NoError(t, err)
+ return tag.(PlcTag)
+}
+
+func TestParsePlcValueSingleDINT(t *testing.T) {
+ value, err := parsePlcValue(mustTag(t, "%rate:DINT"), []byte{0x16, 0x02, 0x00, 0x00}, readWriteModel.CIPDataTypeCode_DINT)
+ require.NoError(t, err)
+ assert.Equal(t, int32(0x216), value.GetInt32())
+}
+
+func TestParsePlcValueSingleREAL(t *testing.T) {
+ raw := binary.LittleEndian.AppendUint32(nil, math.Float32bits(1.5))
+ value, err := parsePlcValue(mustTag(t, "%f:REAL"), raw, readWriteModel.CIPDataTypeCode_REAL)
+ require.NoError(t, err)
+ assert.Equal(t, float32(1.5), value.GetFloat32())
+}
+
+func TestParsePlcValueSingleBOOL(t *testing.T) {
+ value, err := parsePlcValue(mustTag(t, "%b:BOOL"), []byte{0x01}, readWriteModel.CIPDataTypeCode_BOOL)
+ require.NoError(t, err)
+ assert.True(t, value.GetBool())
+}
+
+func TestParsePlcValueDINTArray(t *testing.T) {
+ raw := []byte{0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00}
+ value, err := parsePlcValue(mustTag(t, "%arr[0]:DINT:2"), raw, readWriteModel.CIPDataTypeCode_DINT)
+ require.NoError(t, err)
+ require.True(t, value.IsList())
+ list := value.GetList()
+ require.Len(t, list, 2)
+ assert.Equal(t, int32(1), list[0].GetInt32())
+ assert.Equal(t, int32(2), list[1].GetInt32())
+}
+
+func TestParsePlcValueShortReplyIsError(t *testing.T) {
+ // 2 DINT elements requested but only 4 bytes returned: must error, not panic (GH-954 thread)
+ _, err := parsePlcValue(mustTag(t, "%arr[0]:DINT:2"), []byte{0x01, 0x00, 0x00, 0x00}, readWriteModel.CIPDataTypeCode_DINT)
+ require.Error(t, err)
+}
+
+func TestParsePlcValueString(t *testing.T) {
+ // structured header: type 0x0FCE (STRING), len 2, 2 pad bytes, then "AB"
+ raw := []byte{0xCE, 0x0F, 0x02, 0x00, 0x00, 0x00, 0x41, 0x42}
+ value, err := parsePlcValue(mustTag(t, "%s:STRING"), raw, readWriteModel.CIPDataTypeCode_STRING)
+ require.NoError(t, err)
+ assert.Equal(t, "AB", value.GetString())
+}
+
+func TestEncodeValueDINT(t *testing.T) {
+ raw, err := encodeValue(spiValues.NewPlcDINT(0x216), readWriteModel.CIPDataTypeCode_DINT)
+ require.NoError(t, err)
+ assert.Equal(t, []byte{0x16, 0x02, 0x00, 0x00}, raw)
+}
+
+func TestEncodeValueREAL(t *testing.T) {
+ raw, err := encodeValue(spiValues.NewPlcREAL(1.0), readWriteModel.CIPDataTypeCode_REAL)
+ require.NoError(t, err)
+ assert.Equal(t, []byte{0x00, 0x00, 0x80, 0x3F}, raw)
+}
+
+func TestEncodeValueBOOL(t *testing.T) {
+ raw, err := encodeValue(spiValues.NewPlcBOOL(true), readWriteModel.CIPDataTypeCode_BOOL)
+ require.NoError(t, err)
+ assert.Equal(t, []byte{0x01}, raw)
+}
+
+func TestEncodeValueSTRING(t *testing.T) {
+ raw, err := encodeValue(spiValues.NewPlcSTRING("AB"), readWriteModel.CIPDataTypeCode_STRING)
+ require.NoError(t, err)
+ assert.Equal(t, []byte{0x02, 0x00, 0x00, 0x00, 0x41, 0x42}, raw)
+}
+
+func TestDecodeResponseCode(t *testing.T) {
+ assert.Equal(t, apiModel.PlcResponseCode_OK, decodeResponseCode(0))
+ assert.Equal(t, apiModel.PlcResponseCode_INTERNAL_ERROR, decodeResponseCode(5))
+}
diff --git a/plc4go/internal/eip/Writer.go b/plc4go/internal/eip/Writer.go
index 923945293e..27abeedec6 100644
--- a/plc4go/internal/eip/Writer.go
+++ b/plc4go/internal/eip/Writer.go
@@ -21,7 +21,6 @@ package eip
import (
"context"
- "encoding/binary"
"runtime/debug"
"strings"
"sync"
@@ -29,7 +28,6 @@ import (
"github.com/rs/zerolog"
apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
- apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
readWriteModel "github.com/apache/plc4x/plc4go/protocols/eip/readwrite/model"
"github.com/apache/plc4x/plc4go/spi"
"github.com/apache/plc4x/plc4go/spi/errors"
@@ -91,7 +89,7 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
if isArray {
dataLength += 2
}
- data, err := encodeValue(value, eipTag.GetType(), elements)
+ data, err := encodeValue(value, eipTag.GetType())
if err != nil {
utils.DeliverResult(m.log, result, spiModel.NewDefaultPlcWriteRequestResult(writeRequest, nil, errors.Wrapf(err, "Error encoding value for eipTag %s", tagName)))
return
@@ -283,36 +281,6 @@ func (m *Writer) Write(ctx context.Context, writeRequest apiModel.PlcWriteReques
return result
}
-func encodeValue(value apiValues.PlcValue, _type readWriteModel.CIPDataTypeCode, elements uint16) ([]byte, error) {
- buffer := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.LittleEndian))
- switch _type {
- case readWriteModel.CIPDataTypeCode_SINT:
- err := buffer.WriteByte("", value.GetUint8())
- if err != nil {
- return nil, err
- }
- case readWriteModel.CIPDataTypeCode_INT:
- err := buffer.WriteInt16("", 16, value.GetInt16())
- if err != nil {
- return nil, err
- }
- case readWriteModel.CIPDataTypeCode_DINT:
- err := buffer.WriteInt32("", 32, value.GetInt32())
- if err != nil {
- return nil, err
- }
- case readWriteModel.CIPDataTypeCode_REAL:
- err := buffer.WriteFloat64("", 64, value.GetFloat64())
- if err != nil {
- return nil, err
- }
- default:
- // TODO: what is the default type? write nothing?
- //panic("unmapped type: " + strconv.Itoa(int(_type)))
- }
- return buffer.GetBytes(), nil
-}
-
func (m *Writer) ToPlc4xWriteResponse(response readWriteModel.CipService, writeRequest apiModel.PlcWriteRequest) (apiModel.PlcWriteResponse, error) {
responseCodes := map[string]apiModel.PlcResponseCode{}
switch response := response.(type) {