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 2022/08/08 16:39:23 UTC

[plc4x] branch develop updated: fix(plc4go/cbus): fix handling of "!" errors

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 f55a931e5 fix(plc4go/cbus): fix handling of "!" errors
f55a931e5 is described below

commit f55a931e5c0147bad24d13edb7391f9c472f3f92
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon Aug 8 18:39:16 2022 +0200

    fix(plc4go/cbus): fix handling of "!" errors
---
 plc4go/internal/cbus/Browser.go      | 28 +++++++++++++++++++++++++---
 plc4go/internal/cbus/Connection.go   |  2 +-
 plc4go/internal/cbus/MessageCodec.go |  5 +++++
 plc4go/internal/cbus/Reader.go       | 15 +++++++++++++++
 4 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/plc4go/internal/cbus/Browser.go b/plc4go/internal/cbus/Browser.go
index d2abc351f..d3ca94512 100644
--- a/plc4go/internal/cbus/Browser.go
+++ b/plc4go/internal/cbus/Browser.go
@@ -59,11 +59,14 @@ func (m Browser) BrowseWithInterceptor(browseRequest apiModel.PlcBrowseRequest,
 			var queryResults []apiModel.PlcBrowseFoundField
 			switch field := field.(type) {
 			case *unitInfoField:
+				allUnits := false
 				var units []readWriteModel.UnitAddress
+				allAttributes := false
 				var attributes []readWriteModel.Attribute
 				if unitAddress := field.unitAddress; unitAddress != nil {
 					units = append(units, *unitAddress)
 				} else {
+					allUnits = true
 					for i := 0; i <= 0xFF; i++ {
 						units = append(units, readWriteModel.NewUnitAddress(byte(i)))
 					}
@@ -71,22 +74,41 @@ func (m Browser) BrowseWithInterceptor(browseRequest apiModel.PlcBrowseRequest,
 				if attribute := field.attribute; attribute != nil {
 					attributes = append(attributes, *attribute)
 				} else {
+					allAttributes = true
 					for _, attribute := range readWriteModel.AttributeValues {
 						attributes = append(attributes, attribute)
 					}
 				}
+
+				if allUnits {
+					log.Info().Msg("Querying all units")
+				}
 			unitLoop:
 				for _, unit := range units {
+					unitAddress := unit.GetAddress()
+					if !allUnits && allAttributes {
+						log.Info().Msgf("Querying all attributes of unit %d", unitAddress)
+					}
+					event := log.Info()
+					if allUnits {
+						event = log.Debug()
+					}
+					event.Msgf("Query unit  %d", unitAddress)
 					for _, attribute := range attributes {
-						unitAddress := unit.GetAddress()
-						log.Info().Msgf("unit %d: Query %s", unitAddress, attribute)
+						if !allUnits && !allAttributes {
+							log.Info().Msgf("Querying attribute %s of unit %d", attribute, unitAddress)
+						} else {
+							event.Msgf("unit %d: Query %s", unitAddress, attribute)
+						}
 						readFieldName := fmt.Sprintf("%s/%d/%s", fieldName, unitAddress, attribute)
 						readRequest, _ := m.connection.ReadRequestBuilder().
 							AddField(readFieldName, NewCALIdentifyField(unit, attribute, 1)).
 							Build()
 						requestResult := <-readRequest.Execute()
 						if err := requestResult.GetErr(); err != nil {
-							log.Info().Err(err).Msgf("unit %d: Can't read attribute %s", unitAddress, attribute)
+							if !allUnits && !allAttributes {
+								event.Err(err).Msgf("unit %d: Can't read attribute %s", unitAddress, attribute)
+							}
 							continue unitLoop
 						}
 						queryResults = append(queryResults, &model.DefaultPlcBrowseQueryResult{
diff --git a/plc4go/internal/cbus/Connection.go b/plc4go/internal/cbus/Connection.go
index bcab1c603..56258d7b7 100644
--- a/plc4go/internal/cbus/Connection.go
+++ b/plc4go/internal/cbus/Connection.go
@@ -43,7 +43,7 @@ func (t *AlphaGenerator) getAndIncrement() byte {
 	t.lock.Lock()
 	defer t.lock.Unlock()
 	// If we've reached the max value 'z', reset back to 'g'
-	if t.currentAlpha >= 'z' {
+	if t.currentAlpha > 'z' {
 		t.currentAlpha = 'g'
 	}
 	result := t.currentAlpha
diff --git a/plc4go/internal/cbus/MessageCodec.go b/plc4go/internal/cbus/MessageCodec.go
index 4c3a912db..ef58c5fb4 100644
--- a/plc4go/internal/cbus/MessageCodec.go
+++ b/plc4go/internal/cbus/MessageCodec.go
@@ -119,6 +119,11 @@ func (m *MessageCodec) Receive() (spi.Message, error) {
 		log.Trace().Msg("Nothing to read")
 		return nil, nil
 	}
+	if bytes, err := ti.PeekReadableBytes(1); err != nil && (bytes[0] == '!') {
+		_, _ = ti.Read(1)
+		// TODO: a exclamation mark doesn't have a CR&LF in contrast to the documentation
+		return readwriteModel.CBusMessageParse(utils.NewReadBufferByteBased([]byte("!\r\n")), true, m.requestContext, m.cbusOptions)
+	}
 	// TODO: we might get a simple confirmation like g# without anything other... so we might need to handle that
 
 	peekedBytes, err := ti.PeekReadableBytes(readableBytes)
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index 8c87455a0..3477b107e 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -110,6 +110,15 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 						}
 						confirmation, ok := messageToClient.GetReply().(readWriteModel.ReplyOrConfirmationConfirmationExactly)
 						if !ok {
+							reply, ok := messageToClient.GetReply().(readWriteModel.ReplyOrConfirmationReplyExactly)
+							if !ok {
+								return false
+							}
+							_, ok = reply.GetReply().(readWriteModel.ServerErrorReplyExactly)
+							if ok {
+								// This means we must handle this below
+								return true
+							}
 							return false
 						}
 						return confirmation.GetConfirmation().GetAlpha().GetCharacter() == messageToSend.(readWriteModel.CBusMessageToServer).GetRequest().(readWriteModel.RequestCommand).GetAlpha().GetCharacter()
@@ -119,6 +128,12 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 						log.Trace().Msg("convert response to ")
 						cbusMessage := receivedMessage.(readWriteModel.CBusMessage)
 						messageToClient := cbusMessage.(readWriteModel.CBusMessageToClient)
+						if _, ok := messageToClient.GetReply().(readWriteModel.ReplyOrConfirmationReplyExactly); ok {
+							log.Debug().Msg("We got a server failure")
+							addResponseCode(fieldNameCopy, model.PlcResponseCode_INVALID_DATA)
+							requestWasOk <- false
+							return transaction.EndRequest()
+						}
 						replyOrConfirmationConfirmation := messageToClient.GetReply().(readWriteModel.ReplyOrConfirmationConfirmationExactly)
 						if !replyOrConfirmationConfirmation.GetConfirmation().GetIsSuccess() {
 							var responseCode model.PlcResponseCode