Search in sources :

Example 1 with AbEthField

use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.

the class Plc4xAbEthProtocol method decodeReadResponse.

private PlcResponse decodeReadResponse(CIPEncapsulationReadResponse plcReadResponse, PlcRequestContainer requestContainer) {
    PlcReadRequest plcReadRequest = (PlcReadRequest) requestContainer.getRequest();
    Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
    for (String fieldName : plcReadRequest.getFieldNames()) {
        AbEthField field = (AbEthField) plcReadRequest.getField(fieldName);
        PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus());
        PlcValue plcValue = null;
        if (responseCode == PlcResponseCode.OK) {
            try {
                switch(field.getFileType()) {
                    case // output as single bytes
                    INTEGER:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (data.size() == 1) {
                                plcValue = new PlcINT(data.get(0));
                            } else {
                                plcValue = IEC61131ValueHandler.of(data);
                            }
                        }
                        break;
                    case WORD:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (((data.get(1) >> 7) & 1) == 0) {
                                // positive number
                                plcValue = IEC61131ValueHandler.of((data.get(1) << 8) + data.get(0));
                            } else {
                                // negative number
                                plcValue = IEC61131ValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
                            }
                        }
                        break;
                    case DWORD:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (((data.get(3) >> 7) & 1) == 0) {
                                // positive number
                                plcValue = IEC61131ValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));
                            } else {
                                // negative number
                                plcValue = IEC61131ValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((~(data.get(2) - 1) & 0b11111111) << 16) + ((~(data.get(1) - 1) & 0b11111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
                            }
                        }
                        break;
                    case SINGLEBIT:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (field.getBitNumber() < 8) {
                                // read from first byte
                                plcValue = IEC61131ValueHandler.of((data.get(0) & (1 << field.getBitNumber())) != 0);
                            } else {
                                // read from second byte
                                plcValue = IEC61131ValueHandler.of((data.get(1) & (1 << (field.getBitNumber() - 8))) != 0);
                            }
                        }
                        break;
                    default:
                        logger.warn("Problem during decoding of field {}: Decoding of file type not implemented; " + "FieldInformation: {}", fieldName, field);
                }
            } catch (Exception e) {
                logger.warn("Some other error occurred casting field {}, FieldInformation: {}", fieldName, field, e);
            }
        }
        ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
        values.put(fieldName, result);
    }
    return new DefaultPlcReadResponse(plcReadRequest, values);
}
Also used : PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) AbEthField(org.apache.plc4x.java.abeth.field.AbEthField)

Example 2 with AbEthField

use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.

the class AbEthProtocolLogic method read.

@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
    // TODO: Warning ... we are senging one request per field ... the result has to be merged back together ...
    for (String fieldName : readRequest.getFieldNames()) {
        PlcField field = readRequest.getField(fieldName);
        if (!(field instanceof AbEthField)) {
            logger.error("The field should have been of type AbEthField");
        }
        AbEthField abEthField = (AbEthField) field;
        DF1RequestProtectedTypedLogicalRead logicalRead = new DF1RequestProtectedTypedLogicalRead(abEthField.getByteSize(), abEthField.getFileNumber(), abEthField.getFileType().getTypeCode(), abEthField.getElementNumber(), // Subelementnumber default to zero
        (short) 0);
        final int transactionCounter = transactionCounterGenerator.incrementAndGet();
        // If we've reached the max value for a 16 bit transaction identifier, reset back to 1
        if (transactionCounterGenerator.get() == 0xFFFF) {
            transactionCounterGenerator.set(1);
        }
        // origin/sender: constant = 5
        DF1RequestMessage requestMessage = new DF1CommandRequestMessage((short) configuration.getStation(), (short) 5, (short) 0, transactionCounter, logicalRead);
        CIPEncapsulationReadRequest read = new CIPEncapsulationReadRequest(sessionHandle, 0, emptySenderContext, 0, requestMessage);
        CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
        RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
        transaction.submit(() -> context.sendRequest(read).expectResponse(CIPEncapsulationPacket.class, REQUEST_TIMEOUT).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).check(p -> p instanceof CIPEncapsulationReadResponse).unwrap(p -> (CIPEncapsulationReadResponse) p).check(p -> p.getResponse().getTransactionCounter() == transactionCounter).handle(p -> {
            PlcResponse response = decodeReadResponse(p, readRequest);
            // TODO: Not sure how to merge things back together ...
            // future.complete(response);
            // Finish the request-transaction.
            transaction.endRequest();
        // future.complete(((PlcReadResponse) decodeReadResponse(p, ((InternalPlcReadRequest) readRequest))));
        }));
        // TODO: This aborts reading other fields after sending the first fields request ... refactor.
        return future;
    }
    // TODO: Should return an aggregated future ....
    return null;
}
Also used : org.apache.plc4x.java.api.value(org.apache.plc4x.java.api.value) org.apache.plc4x.java.abeth.readwrite(org.apache.plc4x.java.abeth.readwrite) Arrays(java.util.Arrays) LoggerFactory(org.slf4j.LoggerFactory) PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) PlcResponse(org.apache.plc4x.java.api.messages.PlcResponse) AbEthConfiguration(org.apache.plc4x.java.abeth.configuration.AbEthConfiguration) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) PlcINT(org.apache.plc4x.java.spi.values.PlcINT) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConversationContext(org.apache.plc4x.java.spi.ConversationContext) Duration(java.time.Duration) Map(java.util.Map) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) Plc4xProtocolBase(org.apache.plc4x.java.spi.Plc4xProtocolBase) AbEthField(org.apache.plc4x.java.abeth.field.AbEthField) Logger(org.slf4j.Logger) PlcField(org.apache.plc4x.java.api.model.PlcField) IEC61131ValueHandler(org.apache.plc4x.java.spi.values.IEC61131ValueHandler) HasConfiguration(org.apache.plc4x.java.spi.configuration.HasConfiguration) List(java.util.List) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) PlcField(org.apache.plc4x.java.api.model.PlcField) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) CompletableFuture(java.util.concurrent.CompletableFuture) PlcResponse(org.apache.plc4x.java.api.messages.PlcResponse) AbEthField(org.apache.plc4x.java.abeth.field.AbEthField)

Example 3 with AbEthField

use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.

the class AbEthProtocolLogic method decodeReadResponse.

private PlcResponse decodeReadResponse(CIPEncapsulationReadResponse plcReadResponse, PlcReadRequest plcReadRequest) {
    Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
    for (String fieldName : plcReadRequest.getFieldNames()) {
        AbEthField field = (AbEthField) plcReadRequest.getField(fieldName);
        PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus());
        PlcValue plcValue = null;
        if (responseCode == PlcResponseCode.OK) {
            try {
                switch(field.getFileType()) {
                    case // output as single bytes
                    INTEGER:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (data.size() == 1) {
                                plcValue = new PlcINT(data.get(0));
                            } else {
                                plcValue = IEC61131ValueHandler.of(data);
                            }
                        }
                        break;
                    case WORD:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (((data.get(1) >> 7) & 1) == 0) {
                                // positive number
                                plcValue = IEC61131ValueHandler.of((data.get(1) << 8) + data.get(0));
                            } else {
                                // negative number
                                plcValue = IEC61131ValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
                            }
                        }
                        break;
                    case DWORD:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (((data.get(3) >> 7) & 1) == 0) {
                                // positive number
                                plcValue = IEC61131ValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));
                            } else {
                                // negative number
                                plcValue = IEC61131ValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((~(data.get(2) - 1) & 0b11111111) << 16) + ((~(data.get(1) - 1) & 0b11111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
                            }
                        }
                        break;
                    case SINGLEBIT:
                        if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
                            DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                            List<Short> data = df1PTLR.getData();
                            if (field.getBitNumber() < 8) {
                                // read from first byte
                                plcValue = IEC61131ValueHandler.of((data.get(0) & (1 << field.getBitNumber())) != 0);
                            } else {
                                // read from second byte
                                plcValue = IEC61131ValueHandler.of((data.get(1) & (1 << (field.getBitNumber() - 8))) != 0);
                            }
                        }
                        break;
                    default:
                        logger.warn("Problem during decoding of field {}: Decoding of file type not implemented; " + "FieldInformation: {}", fieldName, field);
                }
            } catch (Exception e) {
                logger.warn("Some other error occurred casting field {}, FieldInformation: {}", fieldName, field, e);
            }
        }
        ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
        values.put(fieldName, result);
    }
    // TODO: Double check if it's really a InternalPlcReadRequest ...
    return new DefaultPlcReadResponse(plcReadRequest, values);
}
Also used : HashMap(java.util.HashMap) PlcINT(org.apache.plc4x.java.spi.values.PlcINT) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) AbEthField(org.apache.plc4x.java.abeth.field.AbEthField)

Example 4 with AbEthField

use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.

the class Plc4xAbEthProtocol method encode.

@Override
protected void encode(ChannelHandlerContext ctx, PlcRequestContainer msg, List<Object> out) throws Exception {
    logger.trace("Encoding {}", msg);
    PlcRequest request = msg.getRequest();
    // reset counter since two byte values are possible in DF1
    if (transactionCounterGenerator.get() > 65000) {
        transactionCounterGenerator.set(10);
    }
    if (request instanceof PlcReadRequest) {
        PlcReadRequest readRequest = (PlcReadRequest) msg.getRequest();
        for (String fieldName : readRequest.getFieldNames()) {
            PlcField field = readRequest.getField(fieldName);
            if (!(field instanceof AbEthField)) {
                throw new PlcProtocolException("The field should have been of type AbEthField");
            }
            AbEthField abEthField = (AbEthField) field;
            DF1RequestProtectedTypedLogicalRead logicalRead = new DF1RequestProtectedTypedLogicalRead(abEthField.getByteSize(), abEthField.getFileNumber(), abEthField.getFileType().getTypeCode(), abEthField.getElementNumber(), // Subelementnumber default to zero
            (short) 0);
            // origin/sender: constant = 5
            DF1RequestMessage requestMessage = new DF1CommandRequestMessage((short) station, (short) 5, (short) 0, transactionCounterGenerator.incrementAndGet(), logicalRead);
            CIPEncapsulationReadRequest read = new CIPEncapsulationReadRequest(sessionHandle, 0, emptySenderContext, 0, requestMessage);
            requests.put(requestMessage.getTransactionCounter(), msg);
            out.add(read);
        }
    } else {
        ctx.fireExceptionCaught(new PlcProtocolException("Unsupported request type " + request.getClass().getName()));
    }
}
Also used : PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) PlcRequest(org.apache.plc4x.java.api.messages.PlcRequest) PlcField(org.apache.plc4x.java.api.model.PlcField) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) AbEthField(org.apache.plc4x.java.abeth.field.AbEthField)

Aggregations

AbEthField (org.apache.plc4x.java.abeth.field.AbEthField)4 PlcReadRequest (org.apache.plc4x.java.api.messages.PlcReadRequest)3 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)3 DefaultPlcReadResponse (org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse)3 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)3 HashMap (java.util.HashMap)2 PlcProtocolException (org.apache.plc4x.java.api.exceptions.PlcProtocolException)2 PlcField (org.apache.plc4x.java.api.model.PlcField)2 PlcINT (org.apache.plc4x.java.spi.values.PlcINT)2 Duration (java.time.Duration)1 Arrays (java.util.Arrays)1 List (java.util.List)1 Map (java.util.Map)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AbEthConfiguration (org.apache.plc4x.java.abeth.configuration.AbEthConfiguration)1 org.apache.plc4x.java.abeth.readwrite (org.apache.plc4x.java.abeth.readwrite)1 PlcReadResponse (org.apache.plc4x.java.api.messages.PlcReadResponse)1 PlcRequest (org.apache.plc4x.java.api.messages.PlcRequest)1 PlcResponse (org.apache.plc4x.java.api.messages.PlcResponse)1