use of org.apache.plc4x.java.api.messages.PlcResponse in project plc4x by apache.
the class Plc4XDf1Protocol method decode.
@Override
protected void decode(ChannelHandlerContext ctx, DF1Symbol msg, List<Object> out) throws Exception {
logger.debug("Received DF1 Command incoming {}", msg);
if (msg instanceof DF1SymbolMessageFrameNAK) {
logger.warn("Received a response NAK, notify all requests");
for (Map.Entry<Integer, PlcRequestContainer> entry : requests.entrySet()) {
entry.getValue().getResponseFuture().complete(new DefaultPlcReadResponse((PlcReadRequest) entry.getValue().getRequest(), Collections.singletonMap("erster", new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcDINT(-1)))));
}
return;
} else if (msg instanceof DF1SymbolMessageFrameACK) {
logger.warn("Received a response ACK :D");
return;
}
assert msg instanceof DF1SymbolMessageFrame;
DF1Command command = ((DF1SymbolMessageFrame) msg).getCommand();
int transactionId = command.getTransactionCounter();
if (!requests.containsKey(transactionId)) {
logger.warn("Received a response to unknown transaction id {}", transactionId);
ctx.fireExceptionCaught(new RuntimeException("Received a response to unknown transaction id"));
ctx.close();
return;
}
// As every response has a matching request, get this request based on the tpdu.
PlcRequestContainer requestContainer = requests.remove(transactionId);
PlcRequest request = requestContainer.getRequest();
// Handle the response.
PlcResponse response = null;
if (request instanceof PlcReadRequest) {
/*
Things to do
- check response code (if there is something like that?
- cast the bytes to right datatype
- create Response
*/
// We can do this as we have only one fieldName in DF1
final String fieldName = ((PlcReadRequest) request).getFieldNames().iterator().next();
// TODO can there be another code than ok?
final PlcResponseCode responseCode = PlcResponseCode.OK;
// TODO maybe check for different status bytes
final Df1Field field = (Df1Field) ((PlcReadRequest) request).getField(fieldName);
// Cast byte and create response item
PlcValue responseItem = null;
byte[] data = ((DF1UnprotectedReadResponse) command).getData();
switch(field.getDataType()) {
case BIT:
break;
case INTEGER:
// TODO: type conversion is untested
responseItem = new PlcDINT((int) data[0] + ((int) data[1] << 8));
break;
case FLOAT:
break;
case BIT_STRING:
break;
case ARRAY:
break;
// TODO add all other cases here...
default:
throw new NotImplementedException("The DataType " + field.getDataType() + " is currently not implemented!");
}
response = new DefaultPlcReadResponse(((PlcReadRequest) request), Collections.singletonMap(fieldName, new ResponseItem<>(responseCode, responseItem)));
} else if (request instanceof PlcWriteRequest) {
logger.warn("Writing is currently not implemented but received a write response?!");
ctx.close();
throw new NotImplementedException("This is currently not implemented!");
}
// Confirm the response being handled.
if (response != null) {
requestContainer.getResponseFuture().complete(response);
}
}
use of org.apache.plc4x.java.api.messages.PlcResponse in project plc4x by apache.
the class Plc4xAbEthProtocol method decode.
@Override
protected void decode(ChannelHandlerContext ctx, CIPEncapsulationPacket packet, List<Object> out) throws Exception {
logger.trace("Received {}, decoding...", packet);
if (packet instanceof CIPEncapsulationConnectionResponse) {
CIPEncapsulationConnectionResponse connectionResponse = (CIPEncapsulationConnectionResponse) packet;
// Save the session handle
sessionHandle = connectionResponse.getSessionHandle();
// Tell Netty we're finished connecting
ctx.channel().pipeline().fireUserEventTriggered(new ConnectedEvent());
} else {
// We're currently just expecting responses.
if (!(packet instanceof CIPEncapsulationReadResponse)) {
return;
}
CIPEncapsulationReadResponse cipResponse = (CIPEncapsulationReadResponse) packet;
int transactionCounter = cipResponse.getResponse().getTransactionCounter();
if (!requests.containsKey(transactionCounter)) {
ctx.fireExceptionCaught(new PlcProtocolException("Couldn't find request for response with transaction counter " + transactionCounter));
return;
}
PlcRequestContainer requestContainer = requests.remove(transactionCounter);
PlcRequest request = requestContainer.getRequest();
PlcResponse response = null;
if (request instanceof PlcReadRequest) {
response = decodeReadResponse(cipResponse, requestContainer);
} else {
ctx.fireExceptionCaught(new PlcProtocolException("Unsupported request type " + request.getClass().getName()));
}
// Confirm the response being handled.
if (response != null) {
requestContainer.getResponseFuture().complete(response);
}
}
}
use of org.apache.plc4x.java.api.messages.PlcResponse in project plc4x by apache.
the class ApiResponseHandler method executeApiResponse.
public void executeApiResponse() {
assert synchronizer != null;
if (synchronizer.responseFuture == null) {
throw new DriverTestsuiteException("No response expected.");
}
PlcResponse plcResponse;
try {
plcResponse = synchronizer.responseFuture.get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new DriverTestsuiteException("Got no response within 5000ms.", e);
} catch (Exception e) {
throw new DriverTestsuiteException("Got no response within 5000ms.", e);
}
// Reset the future.
synchronizer.responseFuture = null;
final String serializedResponse = serializeToXmlString((Serializable) plcResponse);
ApiValidator.validateApiMessage(payload, serializedResponse);
}
use of org.apache.plc4x.java.api.messages.PlcResponse 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;
}
Aggregations