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 2021/03/31 11:57:48 UTC

[plc4x] branch develop updated: plc4go: ads symbolic resolving works (just in the wrong mode) + currently works in big endian opposed to the required little endian. Once this is resolved the ignore list entry for "Single element symbolic read request" can be removed

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


The following commit(s) were added to refs/heads/develop by this push:
     new 19b585f  plc4go: ads symbolic resolving works (just in the wrong mode) + currently works in big endian opposed to the required little endian. Once this is resolved the ignore list entry for "Single element symbolic read request" can be removed
19b585f is described below

commit 19b585f9f7921cc7c9e9bfbbef122c306d8678c0
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Mar 31 13:57:26 2021 +0200

    plc4go: ads symbolic resolving works (just in the wrong mode)
    + currently works in big endian opposed to the required little endian. Once this is resolved the ignore list entry for "Single element symbolic read request" can be removed
---
 plc4go/internal/plc4go/ads/Field.go            | 32 ++++++++++++++++++++++----
 plc4go/internal/plc4go/ads/FieldHandler.go     |  8 +++----
 plc4go/internal/plc4go/ads/Reader.go           | 26 ++++++++++++++-------
 plc4go/internal/plc4go/ads/Writer.go           |  6 ++---
 plc4go/internal/plc4go/ads/fieldtype_string.go |  8 +++----
 5 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/plc4go/internal/plc4go/ads/Field.go b/plc4go/internal/plc4go/ads/Field.go
index 7b878ca..9461829 100644
--- a/plc4go/internal/plc4go/ads/Field.go
+++ b/plc4go/internal/plc4go/ads/Field.go
@@ -43,6 +43,30 @@ func (m PlcField) GetQuantity() uint16 {
 	return 1
 }
 
+func (m PlcField) GetDatatype() model2.AdsDataType {
+	return m.Datatype
+}
+
+func (m PlcField) GetStringLength() int32 {
+	return m.StringLength
+}
+
+func (m PlcField) GetAddressString() string {
+	return fmt.Sprintf("%dx%05d%05d:%s", m.FieldType, m.StringLength, m.NumberOfElements, m.Datatype.String())
+}
+
+type AdsPlcField interface {
+	GetDatatype() model2.AdsDataType
+	GetStringLength() int32
+}
+
+func castToAdsFieldFromPlcField(plcField model.PlcField) (AdsPlcField, error) {
+	if adsField, ok := plcField.(AdsPlcField); ok {
+		return adsField, nil
+	}
+	return nil, errors.Errorf("couldn't %T cast to AdsPlcField", plcField)
+}
+
 type DirectPlcField struct {
 	IndexGroup  uint32
 	IndexOffset uint32
@@ -74,7 +98,7 @@ func castToDirectAdsFieldFromPlcField(plcField model.PlcField) (DirectPlcField,
 	if adsField, ok := plcField.(DirectPlcField); ok {
 		return adsField, nil
 	}
-	return DirectPlcField{}, errors.New("couldn't cast to AdsPlcField")
+	return DirectPlcField{}, errors.Errorf("couldn't %T cast to DirectPlcField", plcField)
 }
 
 func (m DirectPlcField) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
@@ -117,9 +141,9 @@ func (m SymbolicPlcField) GetAddressString() string {
 }
 
 func newAdsSymbolicPlcField(symbolicAddress string, adsDataType model2.AdsDataType, stringLength int32, numberOfElements int64) (model.PlcField, error) {
-	fieldType := SymbolicField
+	fieldType := SymbolicAdsField
 	if stringLength > 0 {
-		fieldType = SymbolicStringField
+		fieldType = SymbolicAdsStringField
 	}
 	return SymbolicPlcField{
 		SymbolicAddress: symbolicAddress,
@@ -147,7 +171,7 @@ func castToSymbolicPlcFieldFromPlcField(plcField model.PlcField) (SymbolicPlcFie
 	if adsField, ok := plcField.(SymbolicPlcField); ok {
 		return adsField, nil
 	}
-	return SymbolicPlcField{}, errors.New("couldn't cast to AdsPlcField")
+	return SymbolicPlcField{}, errors.Errorf("couldn't cast %T to SymbolicPlcField", plcField)
 }
 
 func (m SymbolicPlcField) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
diff --git a/plc4go/internal/plc4go/ads/FieldHandler.go b/plc4go/internal/plc4go/ads/FieldHandler.go
index 3bfe85d..0711df9 100644
--- a/plc4go/internal/plc4go/ads/FieldHandler.go
+++ b/plc4go/internal/plc4go/ads/FieldHandler.go
@@ -34,10 +34,10 @@ type FieldType uint8
 
 //go:generate stringer -type FieldType
 const (
-	DirectAdsStringField FieldType = 0x00
-	DirectAdsField       FieldType = 0x01
-	SymbolicStringField  FieldType = 0x03
-	SymbolicField        FieldType = 0x04
+	DirectAdsStringField   FieldType = 0x00
+	DirectAdsField         FieldType = 0x01
+	SymbolicAdsStringField FieldType = 0x03
+	SymbolicAdsField       FieldType = 0x04
 )
 
 func (i FieldType) GetName() string {
diff --git a/plc4go/internal/plc4go/ads/Reader.go b/plc4go/internal/plc4go/ads/Reader.go
index a177762..cc47905 100644
--- a/plc4go/internal/plc4go/ads/Reader.go
+++ b/plc4go/internal/plc4go/ads/Reader.go
@@ -121,10 +121,8 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 			userdata.Data = readWriteModel.NewAdsReadRequest(adsField.IndexGroup, adsField.IndexOffset, uint32(adsField.Datatype.LengthInBytes()))
 		case DirectAdsField:
 			userdata.Data = readWriteModel.NewAdsReadRequest(adsField.IndexGroup, adsField.IndexOffset, uint32(adsField.Datatype.LengthInBytes()))
-		case SymbolicStringField:
-			panic("implement me")
-		case SymbolicField:
-			panic("implement me")
+		case SymbolicAdsStringField, SymbolicAdsField:
+			panic("we should never reach this point as symbols are resolved before")
 		default:
 			result <- model.PlcReadRequestResult{
 				Request:  readRequest,
@@ -232,7 +230,8 @@ func (m *Reader) resolveField(symbolicField SymbolicPlcField) (DirectPlcField, e
 	)
 	result := make(chan model.PlcReadRequestResult)
 	go func() {
-		m.sendOverTheWire(userdata, nil, result)
+		dummyRequest := plc4goModel.NewDefaultPlcReadRequest(map[string]model.PlcField{"dummy": DirectPlcField{PlcField: PlcField{Datatype: readWriteModel.AdsDataType_UINT32}}}, []string{"dummy"}, nil, nil)
+		m.sendOverTheWire(userdata, dummyRequest, result)
 	}()
 	response := <-result
 	if response.Err != nil {
@@ -240,11 +239,18 @@ func (m *Reader) resolveField(symbolicField SymbolicPlcField) (DirectPlcField, e
 		return DirectPlcField{}, response.Err
 	}
 	handle := response.Response.GetValue(response.Response.GetFieldNames()[0]).GetUint32()
+	log.Debug().Uint32("handle", handle).Str("symbolicAddress", symbolicField.SymbolicAddress).Msg("Resolved symbolic address")
 	directPlcField := DirectPlcField{
 		IndexGroup:  uint32(readWriteModel.ReservedIndexGroups_ADSIGRP_SYM_VALBYHND),
 		IndexOffset: handle,
 		PlcField:    symbolicField.PlcField,
 	}
+	switch directPlcField.FieldType {
+	case SymbolicAdsField:
+		directPlcField.FieldType = DirectAdsField
+	case SymbolicAdsStringField:
+		directPlcField.FieldType = DirectAdsStringField
+	}
 	m.fieldMapping[symbolicField] = directPlcField
 	return directPlcField, nil
 }
@@ -255,7 +261,10 @@ func (m *Reader) ToPlc4xReadResponse(amsTcpPaket readWriteModel.AmsTCPPacket, re
 	case *readWriteModel.AdsReadResponse:
 		readResponse := readWriteModel.CastAdsReadResponse(amsTcpPaket.Userdata.Data)
 		data = utils.Int8ArrayToUint8Array(readResponse.Data)
-		// Pure Boolean ...
+	// Pure Boolean ...
+	case *readWriteModel.AdsReadWriteResponse:
+		readResponse := readWriteModel.CastAdsReadWriteResponse(amsTcpPaket.Userdata.Data)
+		data = utils.Int8ArrayToByteArray(readResponse.Data)
 	default:
 		return nil, errors.Errorf("unsupported response type %T", amsTcpPaket.Userdata.Data.Child)
 	}
@@ -263,7 +272,7 @@ func (m *Reader) ToPlc4xReadResponse(amsTcpPaket readWriteModel.AmsTCPPacket, re
 	// Get the field from the request
 	log.Trace().Msg("get a field from request")
 	fieldName := readRequest.GetFieldNames()[0]
-	field, err := castToDirectAdsFieldFromPlcField(readRequest.GetField(fieldName))
+	field, err := castToAdsFieldFromPlcField(readRequest.GetField(fieldName))
 	if err != nil {
 		return nil, errors.Wrap(err, "error casting to ads-field")
 	}
@@ -271,7 +280,8 @@ func (m *Reader) ToPlc4xReadResponse(amsTcpPaket readWriteModel.AmsTCPPacket, re
 	// Decode the data according to the information from the request
 	log.Trace().Msg("decode data")
 	rb := utils.NewReadBuffer(data)
-	value, err := readWriteModel.DataItemParse(rb, field.Datatype.DataFormatName(), field.StringLength)
+	// TODO: this is wrong as we need to read in little endian
+	value, err := readWriteModel.DataItemParse(rb, field.GetDatatype().DataFormatName(), field.GetStringLength())
 	if err != nil {
 		return nil, errors.Wrap(err, "Error parsing data item")
 	}
diff --git a/plc4go/internal/plc4go/ads/Writer.go b/plc4go/internal/plc4go/ads/Writer.go
index 3525e7b..393aaaf 100644
--- a/plc4go/internal/plc4go/ads/Writer.go
+++ b/plc4go/internal/plc4go/ads/Writer.go
@@ -107,10 +107,8 @@ func (m Writer) Write(writeRequest model.PlcWriteRequest) <-chan model.PlcWriteR
 			panic("implement me")
 		case DirectAdsField:
 			panic("implement me")
-		case SymbolicStringField:
-			panic("implement me")
-		case SymbolicField:
-			panic("implement me")
+		case SymbolicAdsStringField, SymbolicAdsField:
+			panic("we should never reach this point as symbols are resolved before")
 		default:
 			result <- model.PlcWriteRequestResult{
 				Request:  writeRequest,
diff --git a/plc4go/internal/plc4go/ads/fieldtype_string.go b/plc4go/internal/plc4go/ads/fieldtype_string.go
index 9611a20..4b0da39 100644
--- a/plc4go/internal/plc4go/ads/fieldtype_string.go
+++ b/plc4go/internal/plc4go/ads/fieldtype_string.go
@@ -27,18 +27,18 @@ func _() {
 	var x [1]struct{}
 	_ = x[DirectAdsStringField-0]
 	_ = x[DirectAdsField-1]
-	_ = x[SymbolicStringField-3]
-	_ = x[SymbolicField-4]
+	_ = x[SymbolicAdsStringField-3]
+	_ = x[SymbolicAdsField-4]
 }
 
 const (
 	_FieldType_name_0 = "DirectAdsStringFieldDirectAdsField"
-	_FieldType_name_1 = "SymbolicStringFieldSymbolicField"
+	_FieldType_name_1 = "SymbolicAdsStringFieldSymbolicAdsField"
 )
 
 var (
 	_FieldType_index_0 = [...]uint8{0, 20, 34}
-	_FieldType_index_1 = [...]uint8{0, 19, 32}
+	_FieldType_index_1 = [...]uint8{0, 22, 38}
 )
 
 func (i FieldType) String() string {