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);
}
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);
}
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);
}
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");
}
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;
}
}
}
Aggregations