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/07/27 15:41:07 UTC
[plc4x] branch develop updated: fix(cbus): fixed several smaller issues
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 6dfa26e7e fix(cbus): fixed several smaller issues
6dfa26e7e is described below
commit 6dfa26e7e1f4bc544bc399cc2e3176574d5f02fa
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Jul 27 17:40:59 2022 +0200
fix(cbus): fixed several smaller issues
- Extended the plc-simulator for new requests
- fixed some issues decoding in plc4go
---
plc4go/internal/cbus/Driver.go | 6 +-
plc4go/internal/cbus/FieldHandler.go | 3 +-
plc4go/internal/cbus/MessageCodec.go | 13 ++-
plc4go/internal/cbus/Reader.go | 6 +-
.../tests/drivers/tests/manual_cbus_driver_test.go | 9 ++-
.../server/cbus/protocol/CBusServerAdapter.java | 92 +++++++++++++++++++++-
6 files changed, 113 insertions(+), 16 deletions(-)
diff --git a/plc4go/internal/cbus/Driver.go b/plc4go/internal/cbus/Driver.go
index 00ded8e73..c86d53800 100644
--- a/plc4go/internal/cbus/Driver.go
+++ b/plc4go/internal/cbus/Driver.go
@@ -72,9 +72,6 @@ func (m *Driver) GetConnection(transportUrl url.URL, transports map[string]trans
return ch
}
- codec := NewMessageCodec(transportInstance)
- log.Debug().Msgf("working with codec %#v", codec)
-
configuration, err := ParseFromOptions(options)
if err != nil {
log.Error().Err(err).Msgf("Invalid options")
@@ -85,6 +82,9 @@ func (m *Driver) GetConnection(transportUrl url.URL, transports map[string]trans
return ch
}
+ codec := NewMessageCodec(transportInstance, configuration.srchk)
+ log.Debug().Msgf("working with codec %#v", codec)
+
driverContext, err := NewDriverContext(configuration)
if err != nil {
log.Error().Err(err).Msgf("Invalid options")
diff --git a/plc4go/internal/cbus/FieldHandler.go b/plc4go/internal/cbus/FieldHandler.go
index d4192fe78..f210d4afd 100644
--- a/plc4go/internal/cbus/FieldHandler.go
+++ b/plc4go/internal/cbus/FieldHandler.go
@@ -66,7 +66,8 @@ func (m FieldHandler) ParseQuery(query string) (model.PlcField, error) {
statusRequestType = StatusRequestTypeBinaryState
} else if levelArgument := match["startingGroupAddressLabel"]; levelArgument != "" {
statusRequestType = StatusRequestTypeLevel
- decodedHex, _ := hex.DecodeString(match["level"])
+ startingGroupAddressLabelArgument := match["startingGroupAddressLabel"]
+ decodedHex, _ := hex.DecodeString(startingGroupAddressLabelArgument)
if len(decodedHex) != 1 {
panic("invalid state. Should have exactly 1")
}
diff --git a/plc4go/internal/cbus/MessageCodec.go b/plc4go/internal/cbus/MessageCodec.go
index 895d451b0..1a2bb0306 100644
--- a/plc4go/internal/cbus/MessageCodec.go
+++ b/plc4go/internal/cbus/MessageCodec.go
@@ -39,10 +39,10 @@ type MessageCodec struct {
hashEncountered uint
}
-func NewMessageCodec(transportInstance transports.TransportInstance) *MessageCodec {
+func NewMessageCodec(transportInstance transports.TransportInstance, srchk bool) *MessageCodec {
codec := &MessageCodec{
requestContext: readwriteModel.NewRequestContext(false, false, false),
- cbusOptions: readwriteModel.NewCBusOptions(false, false, false, false, false, false, false, false, false),
+ cbusOptions: readwriteModel.NewCBusOptions(false, false, false, false, false, false, false, false, srchk),
}
codec.DefaultCodec = _default.NewDefaultCodec(codec, transportInstance)
return codec
@@ -132,17 +132,22 @@ lookingForTheEnd:
m.lastPackageHash, m.hashEncountered = 0, 0
}
}
- if !pciResponse || !requestToPci {
+ if !pciResponse && !requestToPci {
// Apparently we have not found any message yet
return nil, nil
}
+ packetLength := indexOfCR + 1
+ if pciResponse {
+ packetLength = indexOfLF + 1
+ }
+
// Sanity check
if pciResponse && requestToPci {
panic("Invalid state... Can not be response and request at the same time")
}
- read, err := ti.Read(uint32(indexOfCR + 1))
+ read, err := ti.Read(uint32(packetLength))
if err != nil {
panic("Invalid state... If we have peeked that before we should be able to read that now")
}
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index c590127bb..6eaa35c20 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -141,7 +141,7 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
// TODO: it could be double confirmed but this is not implemented yet
embeddedReply := confirmation.GetEmbeddedReply().(readWriteModel.ReplyOrConfirmationReplyExactly)
- switch reply := embeddedReply.(readWriteModel.ReplyEncodedReply).GetEncodedReply().(type) {
+ switch reply := embeddedReply.GetReply().(readWriteModel.ReplyEncodedReply).GetEncodedReply().(type) {
case readWriteModel.EncodedReplyStandardFormatStatusReplyExactly:
application := reply.GetReply().GetApplication()
// TODO: verify application... this should be the same
@@ -173,17 +173,21 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
// TODO: how should we serialize that???
addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", calData)))
}
+ requestWasOk <- true
return transaction.EndRequest()
},
func(err error) error {
log.Debug().Msgf("Error waiting for field %s", fieldNameCopy)
addResponseCode(fieldNameCopy, model.PlcResponseCode_REQUEST_TIMEOUT)
+ // TODO: ok or not ok?
+ requestWasOk <- true
return transaction.EndRequest()
},
time.Second*1); err != nil {
log.Debug().Err(err).Msgf("Error sending message for field %s", fieldNameCopy)
addResponseCode(fieldNameCopy, model.PlcResponseCode_INTERNAL_ERROR)
_ = transaction.EndRequest()
+ requestWasOk <- false
}
})
if !<-requestWasOk {
diff --git a/plc4go/tests/drivers/tests/manual_cbus_driver_test.go b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
index ce907fad2..43fa084a3 100644
--- a/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
+++ b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
@@ -31,17 +31,18 @@ import (
func TestManualCBusDriver(t *testing.T) {
t.Skip()
- connectionString := "c-bus://192.168.178.101"
+ connectionString := "c-bus://192.168.178.101?srchk=true"
driverManager := plc4go.NewPlcDriverManager()
driverManager.RegisterDriver(cbus.NewDriver())
transports.RegisterTcpTransport(driverManager)
test := testutils.NewManualTestSuite(connectionString, driverManager, t)
test.AddTestCase("status/binary/0x04", true)
+ // TODO: apparently a level means that we get a extended status reply but at the moment it is guarded by exstat
test.AddTestCase("status/level=0x40/0x04", true)
- test.AddTestCase("cal/0/recall=[INTERFACE_OPTIONS_1, 1]", true)
- test.AddTestCase("cal/0/identify=[FirmwareVersion]", true)
- test.AddTestCase("cal/0/gestatus=[0xFF, 1]", true)
+ //test.AddTestCase("cal/0/recall=[INTERFACE_OPTIONS_1, 1]", true)
+ //test.AddTestCase("cal/0/identify=[FirmwareVersion]", true)
+ //test.AddTestCase("cal/0/gestatus=[0xFF, 1]", true)
test.Run()
}
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
index 87c73d19f..74f98ad01 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
@@ -25,6 +25,8 @@ import org.apache.plc4x.simulator.model.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.List;
+
public class CBusServerAdapter extends ChannelInboundHandlerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(CBusServerAdapter.class);
@@ -32,7 +34,7 @@ public class CBusServerAdapter extends ChannelInboundHandlerAdapter {
private Context context;
private static final RequestContext requestContext = new RequestContext(false, false, false);
- private static final CBusOptions cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, false);
+ private static final CBusOptions cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
public CBusServerAdapter(Context context) {
this.context = context;
@@ -56,31 +58,115 @@ public class CBusServerAdapter extends ChannelInboundHandlerAdapter {
}
if (request instanceof RequestDirectCommandAccess) {
RequestDirectCommandAccess requestDirectCommandAccess = (RequestDirectCommandAccess) request;
+ LOGGER.info("Handling RequestDirectCommandAccess\n{}", requestDirectCommandAccess);
// TODO: handle this
return;
}
if (request instanceof RequestCommand) {
RequestCommand requestCommand = (RequestCommand) request;
- // TODO: handle this
+ LOGGER.info("Handling RequestCommand\n{}", requestCommand);
+ CBusCommand cbusCommand = requestCommand.getCbusCommand();
+ LOGGER.info("Handling CBusCommand\n{}", cbusCommand);
+ if (cbusCommand instanceof CBusCommandPointToPoint) {
+ // TODO: handle this
+ return;
+ }
+ if (cbusCommand instanceof CBusCommandPointToMultiPoint) {
+ CBusCommandPointToMultiPoint cBusCommandPointToMultiPoint = (CBusCommandPointToMultiPoint) cbusCommand;
+ CBusPointToMultiPointCommand command = cBusCommandPointToMultiPoint.getCommand();
+ if (command instanceof CBusPointToMultiPointCommandStatus) {
+ CBusPointToMultiPointCommandStatus cBusPointToMultiPointCommandStatus = (CBusPointToMultiPointCommandStatus) command;
+ StatusRequest statusRequest = cBusPointToMultiPointCommandStatus.getStatusRequest();
+ if (statusRequest instanceof StatusRequestBinaryState) {
+ StatusRequestBinaryState statusRequestBinaryState = (StatusRequestBinaryState) statusRequest;
+ StatusHeader statusHeader = new StatusHeader((short) (2 + 1)); // 2 we have always + 1 as we got one status byte
+ // TODO: map actuall values from simulator
+ byte blockStart = 0x0;
+ List<StatusByte> statusBytes = List.of(new StatusByte(GAVState.ON, GAVState.ERROR, GAVState.OFF, GAVState.DOES_NOT_EXIST));
+ // TODO: this might be extended or standard depeding on exstat
+ StandardFormatStatusReply standardFormatStatusReply = new StandardFormatStatusReply(statusHeader, statusRequestBinaryState.getApplication(), blockStart, statusBytes);
+ EncodedReply encodedReply = new EncodedReplyStandardFormatStatusReply((byte) 0xC0, standardFormatStatusReply, cBusOptions, requestContext);
+ ReplyEncodedReply replyEncodedReply = new ReplyEncodedReply((byte) 0xC0, encodedReply, null, cBusOptions, requestContext);
+ ReplyOrConfirmation replyOrConfirmation = new ReplyOrConfirmationReply((byte) 0xFF, replyEncodedReply, new ResponseTermination(), cBusOptions, requestContext);
+ Alpha alpha = requestCommand.getAlpha();
+ if (alpha != null) {
+ Confirmation confirmation = new Confirmation(alpha, null, ConfirmationType.CONFIRMATION_SUCCESSFUL);
+ replyOrConfirmation = new ReplyOrConfirmationConfirmation(alpha.getCharacter(), confirmation, replyOrConfirmation, cBusOptions, requestContext);
+ }
+ CBusMessage response = new CBusMessageToClient(replyOrConfirmation, requestContext, cBusOptions);
+ LOGGER.info("Send binary status response\n{}", response);
+ ctx.writeAndFlush(response);
+ return;
+ }
+ if (statusRequest instanceof StatusRequestBinaryStateDeprecated) {
+ // TODO: handle this
+ return;
+ }
+ if (statusRequest instanceof StatusRequestLevel) {
+ StatusRequestLevel statusRequestLevel = (StatusRequestLevel) statusRequest;
+ ExtendedStatusHeader statusHeader = new ExtendedStatusHeader((short) (3 + 1)); // 2 we have always + 1 as we got one status byte
+ StatusCoding coding = StatusCoding.LEVEL_BY_THIS_SERIAL_INTERFACE;
+ // TODO: map actuall values from simulator
+ byte blockStart = statusRequestLevel.getStartingGroupAddressLabel();
+ List<StatusByte> statusBytes = List.of(new StatusByte(GAVState.ON, GAVState.ERROR, GAVState.OFF, GAVState.DOES_NOT_EXIST));
+ ExtendedFormatStatusReply extendedFormatStatusReply = new ExtendedFormatStatusReply(statusHeader, coding, statusRequestLevel.getApplication(), blockStart, statusBytes);
+ EncodedReply encodedReply = new EncodedReplyExtendedFormatStatusReply((byte) 0xC0, extendedFormatStatusReply, cBusOptions, requestContext);
+ ReplyEncodedReply replyEncodedReply = new ReplyEncodedReply((byte) 0xC0, encodedReply, null, cBusOptions, requestContext);
+ ReplyOrConfirmation replyOrConfirmation = new ReplyOrConfirmationReply((byte) 0xFF, replyEncodedReply, new ResponseTermination(), cBusOptions, requestContext);
+ Alpha alpha = requestCommand.getAlpha();
+ if (alpha != null) {
+ Confirmation confirmation = new Confirmation(alpha, null, ConfirmationType.CONFIRMATION_SUCCESSFUL);
+ replyOrConfirmation = new ReplyOrConfirmationConfirmation(alpha.getCharacter(), confirmation, replyOrConfirmation, cBusOptions, requestContext);
+ }
+ CBusMessage response = new CBusMessageToClient(replyOrConfirmation, requestContext, cBusOptions);
+ LOGGER.info("Send level status response\n{}", response);
+ ctx.writeAndFlush(response);
+ return;
+ }
+ // TODO: handle this
+ return;
+ }
+ if (command instanceof Normal) {
+ // TODO: handle this
+ return;
+ }
+ // TODO: handle this
+ return;
+ }
+ if (cbusCommand instanceof CBusCommandPointToPointToMultiPoint) {
+ // TODO: handle this
+ return;
+ }
+ if (cbusCommand instanceof CBusCommandDeviceManagement) {
+ // TODO: handle this
+ return;
+ }
+
Alpha alpha = requestCommand.getAlpha();
if (alpha != null) {
- Confirmation confirmation = new Confirmation(alpha, null, ConfirmationType.CONFIRMATION_SUCCESSFUL);
+ Confirmation confirmation = new Confirmation(alpha, null, ConfirmationType.NOT_TRANSMITTED_CORRUPTION);
ReplyOrConfirmationConfirmation replyOrConfirmationConfirmation = new ReplyOrConfirmationConfirmation(alpha.getCharacter(), confirmation, null, cBusOptions, requestContext);
CBusMessage response = new CBusMessageToClient(replyOrConfirmationConfirmation, requestContext, cBusOptions);
+ LOGGER.info("Send response\n{}", response);
ctx.writeAndFlush(response);
}
return;
}
if (request instanceof RequestObsolete) {
RequestObsolete requestObsolete = (RequestObsolete) request;
+ LOGGER.info("Handling RequestObsolete\n{}", requestObsolete);
// TODO: handle this
return;
}
if (request instanceof RequestReset) {
+ RequestReset requestReset = (RequestReset) request;
+ LOGGER.info("Handling RequestReset\n{}", requestReset);
// TODO: handle this
return;
}
if (request instanceof RequestSmartConnectShortcut) {
+ RequestSmartConnectShortcut requestSmartConnectShortcut = (RequestSmartConnectShortcut) request;
+ LOGGER.info("Handling RequestSmartConnectShortcut\n{}", requestSmartConnectShortcut);
// TODO: handle this
return;
}