Skip to content

Commit

Permalink
fix(cbus): fixed several smaller issues
Browse files Browse the repository at this point in the history
- Extended the plc-simulator for new requests
- fixed some issues decoding in plc4go
  • Loading branch information
sruehl committed Jul 27, 2022
1 parent 30aa269 commit 6dfa26e
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 16 deletions.
6 changes: 3 additions & 3 deletions plc4go/internal/cbus/Driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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")
Expand Down
3 changes: 2 additions & 1 deletion plc4go/internal/cbus/FieldHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
13 changes: 9 additions & 4 deletions plc4go/internal/cbus/MessageCodec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
}
Expand Down
6 changes: 5 additions & 1 deletion plc4go/internal/cbus/Reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
9 changes: 5 additions & 4 deletions plc4go/tests/drivers/tests/manual_cbus_driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@
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);

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;
Expand All @@ -56,31 +58,115 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
}
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;
}
Expand Down

0 comments on commit 6dfa26e

Please sign in to comment.