Search in sources :

Example 26 with PlcResponseCode

use of org.apache.plc4x.java.api.types.PlcResponseCode in project plc4x by apache.

the class S7ProtocolLogic method decodeReadResponse.

private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest plcReadRequest) throws PlcProtocolException {
    Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
    short errorClass;
    short errorCode;
    if (responseMessage instanceof S7MessageResponseData) {
        S7MessageResponseData messageResponseData = (S7MessageResponseData) responseMessage;
        errorClass = messageResponseData.getErrorClass();
        errorCode = messageResponseData.getErrorCode();
    } else if (responseMessage instanceof S7MessageResponse) {
        S7MessageResponse messageResponse = (S7MessageResponse) responseMessage;
        errorClass = messageResponse.getErrorClass();
        errorCode = messageResponse.getErrorCode();
    } else {
        throw new PlcProtocolException("Unsupported message type " + responseMessage.getClass().getName());
    }
    // If the result contains any form of non-null error code, handle this instead.
    if ((errorClass != 0) || (errorCode != 0)) {
        // This is usually the case if PUT/GET wasn't enabled on the PLC
        if ((errorClass == 129) && (errorCode == 4)) {
            logger.warn("Got an error response from the PLC. This particular response code usually indicates " + "that PUT/GET is not enabled on the PLC.");
            for (String fieldName : plcReadRequest.getFieldNames()) {
                ResponseItem<PlcValue> result = new ResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull());
                values.put(fieldName, result);
            }
            return new DefaultPlcReadResponse(plcReadRequest, values);
        } else {
            logger.warn("Got an unknown error response from the PLC. Error Class: {}, Error Code {}. " + "We probably need to implement explicit handling for this, so please file a bug-report " + "on https://issues.apache.org/jira/projects/PLC4X and ideally attach a WireShark dump " + "containing a capture of the communication.", errorClass, errorCode);
            for (String fieldName : plcReadRequest.getFieldNames()) {
                ResponseItem<PlcValue> result = new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcNull());
                values.put(fieldName, result);
            }
            return new DefaultPlcReadResponse(plcReadRequest, values);
        }
    }
    // In all other cases all went well.
    S7PayloadReadVarResponse payload = (S7PayloadReadVarResponse) responseMessage.getPayload();
    // items from the request as this information is not returned by the PLC.
    if (plcReadRequest.getNumberOfFields() != payload.getItems().size()) {
        throw new PlcProtocolException("The number of requested items doesn't match the number of returned items");
    }
    List<S7VarPayloadDataItem> payloadItems = payload.getItems();
    int index = 0;
    for (String fieldName : plcReadRequest.getFieldNames()) {
        S7Field field = (S7Field) plcReadRequest.getField(fieldName);
        S7VarPayloadDataItem payloadItem = payloadItems.get(index);
        PlcResponseCode responseCode = decodeResponseCode(payloadItem.getReturnCode());
        PlcValue plcValue = null;
        ByteBuf data = Unpooled.wrappedBuffer(payloadItem.getData());
        if (responseCode == PlcResponseCode.OK) {
            try {
                plcValue = parsePlcValue(field, data);
            } catch (Exception e) {
                throw new PlcProtocolException("Error decoding PlcValue", e);
            }
        }
        ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
        values.put(fieldName, result);
        index++;
    }
    return new DefaultPlcReadResponse(plcReadRequest, values);
}
Also used : PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) ByteBuf(io.netty.buffer.ByteBuf) TimeoutException(java.util.concurrent.TimeoutException) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcNull(org.apache.plc4x.java.spi.values.PlcNull) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) S7Field(org.apache.plc4x.java.s7.readwrite.field.S7Field)

Example 27 with PlcResponseCode

use of org.apache.plc4x.java.api.types.PlcResponseCode in project plc4x by apache.

the class S7ProtocolLogic method decodeWriteResponse.

private PlcResponse decodeWriteResponse(S7Message responseMessage, PlcWriteRequest plcWriteRequest) throws PlcProtocolException {
    Map<String, PlcResponseCode> responses = new HashMap<>();
    short errorClass;
    short errorCode;
    if (responseMessage instanceof S7MessageResponseData) {
        S7MessageResponseData messageResponseData = (S7MessageResponseData) responseMessage;
        errorClass = messageResponseData.getErrorClass();
        errorCode = messageResponseData.getErrorCode();
    } else if (responseMessage instanceof S7MessageResponse) {
        S7MessageResponse messageResponse = (S7MessageResponse) responseMessage;
        errorClass = messageResponse.getErrorClass();
        errorCode = messageResponse.getErrorCode();
    } else {
        throw new PlcProtocolException("Unsupported message type " + responseMessage.getClass().getName());
    }
    // If the result contains any form of non-null error code, handle this instead.
    if ((errorClass != 0) || (errorCode != 0)) {
        // This is usually the case if PUT/GET wasn't enabled on the PLC
        if ((errorClass == 129) && (errorCode == 4)) {
            logger.warn("Got an error response from the PLC. This particular response code usually indicates " + "that PUT/GET is not enabled on the PLC.");
            for (String fieldName : plcWriteRequest.getFieldNames()) {
                responses.put(fieldName, PlcResponseCode.ACCESS_DENIED);
            }
            return new DefaultPlcWriteResponse(plcWriteRequest, responses);
        } else {
            logger.warn("Got an unknown error response from the PLC. Error Class: {}, Error Code {}. " + "We probably need to implement explicit handling for this, so please file a bug-report " + "on https://issues.apache.org/jira/projects/PLC4X and ideally attach a WireShark dump " + "containing a capture of the communication.", errorClass, errorCode);
            for (String fieldName : plcWriteRequest.getFieldNames()) {
                responses.put(fieldName, PlcResponseCode.INTERNAL_ERROR);
            }
            return new DefaultPlcWriteResponse(plcWriteRequest, responses);
        }
    }
    // In all other cases all went well.
    S7PayloadWriteVarResponse payload = (S7PayloadWriteVarResponse) responseMessage.getPayload();
    // items from the request as this information is not returned by the PLC.
    if (plcWriteRequest.getNumberOfFields() != payload.getItems().size()) {
        throw new PlcProtocolException("The number of requested items doesn't match the number of returned items");
    }
    List<S7VarPayloadStatusItem> payloadItems = payload.getItems();
    int index = 0;
    for (String fieldName : plcWriteRequest.getFieldNames()) {
        S7VarPayloadStatusItem payloadItem = payloadItems.get(index);
        PlcResponseCode responseCode = decodeResponseCode(payloadItem.getReturnCode());
        responses.put(fieldName, responseCode);
        index++;
    }
    return new DefaultPlcWriteResponse(plcWriteRequest, responses);
}
Also used : PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse)

Example 28 with PlcResponseCode

use of org.apache.plc4x.java.api.types.PlcResponseCode in project plc4x by apache.

the class SimulatedConnection method write.

@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
    Map<String, PlcResponseCode> fields = new HashMap<>();
    for (String fieldName : writeRequest.getFieldNames()) {
        SimulatedField field = (SimulatedField) writeRequest.getField(fieldName);
        PlcValue value = writeRequest.getPlcValue(fieldName);
        device.set(field, value);
        fields.put(fieldName, PlcResponseCode.OK);
    }
    PlcWriteResponse response = new DefaultPlcWriteResponse(writeRequest, fields);
    return CompletableFuture.completedFuture(response);
}
Also used : PlcValue(org.apache.plc4x.java.api.value.PlcValue) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) SimulatedField(org.apache.plc4x.java.simulated.field.SimulatedField) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode)

Example 29 with PlcResponseCode

use of org.apache.plc4x.java.api.types.PlcResponseCode in project plc4x by apache.

the class DefaultPlcWriteResponse method serialize.

@Override
public void serialize(WriteBuffer writeBuffer) throws SerializationException {
    writeBuffer.pushContext("PlcWriteResponse");
    if (request instanceof Serializable) {
        ((Serializable) request).serialize(writeBuffer);
    }
    writeBuffer.pushContext("fields");
    for (Map.Entry<String, PlcResponseCode> fieldEntry : responses.entrySet()) {
        String fieldName = fieldEntry.getKey();
        final PlcResponseCode fieldResponseCode = fieldEntry.getValue();
        String result = fieldResponseCode.name();
        writeBuffer.writeString(fieldName, result.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), result);
    }
    writeBuffer.popContext("fields");
    writeBuffer.popContext("PlcWriteResponse");
}
Also used : Serializable(org.apache.plc4x.java.spi.utils.Serializable) Map(java.util.Map) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode)

Example 30 with PlcResponseCode

use of org.apache.plc4x.java.api.types.PlcResponseCode in project plc4x by apache.

the class Plc4xServerAdapter method channelRead.

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    if (msg instanceof Plc4xMessage) {
        final Plc4xMessage plc4xMessage = (Plc4xMessage) msg;
        switch(plc4xMessage.getRequestType()) {
            case CONNECT_REQUEST:
                {
                    Plc4xConnectRequest request = (Plc4xConnectRequest) plc4xMessage;
                    try (final PlcConnection ignored = driverManager.getConnection(request.getConnectionString())) {
                        // connection.ping().get();
                        final int connectionId = connectionIdGenerator.getAndIncrement();
                        connectionUrls.put(connectionId, request.getConnectionString());
                        Plc4xConnectResponse response = new Plc4xConnectResponse(request.getRequestId(), connectionId, Plc4xResponseCode.OK);
                        ctx.writeAndFlush(response);
                    } catch (Exception e) {
                        Plc4xConnectResponse response = new Plc4xConnectResponse(request.getRequestId(), 0, Plc4xResponseCode.INVALID_ADDRESS);
                        ctx.writeAndFlush(response);
                    }
                    break;
                }
            case READ_REQUEST:
                {
                    final Plc4xReadRequest request = (Plc4xReadRequest) plc4xMessage;
                    String connectionUrl = connectionUrls.get(request.getConnectionId());
                    try (final PlcConnection connection = driverManager.getConnection(connectionUrl)) {
                        // Build a read request for all fields in the request.
                        final PlcReadRequest.Builder builder = connection.readRequestBuilder();
                        for (Plc4xFieldRequest requestField : request.getFields()) {
                            builder.addItem(requestField.getField().getName(), requestField.getField().getFieldQuery());
                        }
                        final PlcReadRequest rr = builder.build();
                        // Execute the query.
                        // (It has to be synchronously when working with the connection cache)
                        final PlcReadResponse apiReadResponse = rr.execute().get();
                        // Create the response.
                        List<Plc4xFieldValueResponse> fields = new ArrayList<>(apiReadResponse.getFieldNames().size());
                        for (Plc4xFieldRequest plc4xRequestField : request.getFields()) {
                            final PlcResponseCode responseCode = apiReadResponse.getResponseCode(plc4xRequestField.getField().getName());
                            Plc4xResponseCode resCode;
                            Plc4xValueType valueType;
                            PlcValue value;
                            if (responseCode == PlcResponseCode.OK) {
                                resCode = Plc4xResponseCode.OK;
                                value = apiReadResponse.getPlcValue(plc4xRequestField.getField().getName());
                                final String valueTypeName = value.getClass().getSimpleName();
                                // Cut off the "Plc" prefix to get the name of the PlcValueType.
                                valueType = Plc4xValueType.valueOf(valueTypeName.substring(3));
                            } else {
                                resCode = Plc4xResponseCode.INVALID_ADDRESS;
                                value = null;
                                valueType = Plc4xValueType.NULL;
                            }
                            fields.add(new Plc4xFieldValueResponse(plc4xRequestField.getField(), resCode, valueType, value));
                        }
                        Plc4xReadResponse response = new Plc4xReadResponse(request.getRequestId(), request.getConnectionId(), Plc4xResponseCode.OK, fields);
                        // Send the response.
                        ctx.writeAndFlush(response);
                    } catch (Exception e) {
                        logger.error("Error executing request", e);
                        Plc4xReadResponse response = new Plc4xReadResponse(request.getRequestId(), request.getConnectionId(), Plc4xResponseCode.INVALID_ADDRESS, Collections.emptyList());
                        ctx.writeAndFlush(response);
                    }
                    break;
                }
            case WRITE_REQUEST:
                final Plc4xWriteRequest plc4xWriteRequest = (Plc4xWriteRequest) plc4xMessage;
                String connectionUrl = connectionUrls.get(plc4xWriteRequest.getConnectionId());
                try (final PlcConnection connection = driverManager.getConnection(connectionUrl)) {
                    // Build a write request for all fields in the request.
                    final PlcWriteRequest.Builder builder = connection.writeRequestBuilder();
                    for (Plc4xFieldValueRequest plc4xRequestField : plc4xWriteRequest.getFields()) {
                        builder.addItem(plc4xRequestField.getField().getName(), plc4xRequestField.getField().getFieldQuery(), plc4xRequestField.getValue().getObject());
                    }
                    final PlcWriteRequest apiWriteRequest = builder.build();
                    // Execute the query
                    // (It has to be synchronously when working with the connection cache)
                    final PlcWriteResponse apiWriteResponse = apiWriteRequest.execute().get();
                    // Create the response.
                    List<Plc4xFieldResponse> plc4xFields = new ArrayList<>(apiWriteResponse.getFieldNames().size());
                    for (Plc4xFieldValueRequest plc4xRequestField : plc4xWriteRequest.getFields()) {
                        final PlcResponseCode apiResponseCode = apiWriteResponse.getResponseCode(plc4xRequestField.getField().getName());
                        Plc4xResponseCode resCode;
                        if (apiResponseCode == PlcResponseCode.OK) {
                            resCode = Plc4xResponseCode.OK;
                        } else {
                            resCode = Plc4xResponseCode.INVALID_ADDRESS;
                        }
                        plc4xFields.add(new Plc4xFieldResponse(plc4xRequestField.getField(), resCode));
                    }
                    Plc4xWriteResponse plc4xWriteResponse = new Plc4xWriteResponse(plc4xWriteRequest.getRequestId(), plc4xWriteRequest.getConnectionId(), Plc4xResponseCode.OK, plc4xFields);
                    // Send the response.
                    ctx.writeAndFlush(plc4xWriteResponse);
                } catch (Exception e) {
                    logger.error("Error executing request", e);
                    Plc4xWriteResponse response = new Plc4xWriteResponse(plc4xWriteRequest.getRequestId(), plc4xWriteRequest.getConnectionId(), Plc4xResponseCode.INVALID_ADDRESS, Collections.emptyList());
                    ctx.writeAndFlush(response);
                }
                break;
        }
    }
}
Also used : ArrayList(java.util.ArrayList) PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) ArrayList(java.util.ArrayList) List(java.util.List) PlcConnection(org.apache.plc4x.java.api.PlcConnection) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest)

Aggregations

PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)31 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)20 PlcValue (org.apache.plc4x.java.api.value.PlcValue)19 DefaultPlcReadResponse (org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse)16 CompletableFuture (java.util.concurrent.CompletableFuture)15 DefaultPlcWriteResponse (org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse)15 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)14 RequestTransactionManager (org.apache.plc4x.java.spi.transaction.RequestTransactionManager)13 Duration (java.time.Duration)11 PlcReadRequest (org.apache.plc4x.java.api.messages.PlcReadRequest)11 PlcField (org.apache.plc4x.java.api.model.PlcField)11 PlcWriteRequest (org.apache.plc4x.java.api.messages.PlcWriteRequest)10 HasConfiguration (org.apache.plc4x.java.spi.configuration.HasConfiguration)10 DefaultPlcReadRequest (org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest)9 DefaultPlcWriteRequest (org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest)9 Collections (java.util.Collections)8 PlcWriteResponse (org.apache.plc4x.java.api.messages.PlcWriteResponse)8 org.apache.plc4x.java.modbus.readwrite (org.apache.plc4x.java.modbus.readwrite)8 ParseException (org.apache.plc4x.java.spi.generation.ParseException)8 List (java.util.List)7