Skip to content

Commit

Permalink
fix(plc4go/cbus): fix handling of "!" errors
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Aug 8, 2022
1 parent c7e1d90 commit f55a931
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
28 changes: 25 additions & 3 deletions plc4go/internal/cbus/Browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,34 +59,56 @@ 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)))
}
}
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{
Expand Down
2 changes: 1 addition & 1 deletion plc4go/internal/cbus/Connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions plc4go/internal/cbus/MessageCodec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions plc4go/internal/cbus/Reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down

0 comments on commit f55a931

Please sign in to comment.