Search in sources :

Example 1 with PlcResponse

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);
    }
}
Also used : PlcRequestContainer(org.apache.plc4x.java.spi.messages.PlcRequestContainer) PlcDINT(org.apache.plc4x.java.spi.values.PlcDINT) PlcRequest(org.apache.plc4x.java.api.messages.PlcRequest) NotImplementedException(org.apache.commons.lang3.NotImplementedException) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcResponse(org.apache.plc4x.java.api.messages.PlcResponse) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) Df1Field(org.apache.plc4x.java.df1.field.Df1Field)

Example 2 with PlcResponse

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);
        }
    }
}
Also used : PlcRequestContainer(org.apache.plc4x.java.spi.messages.PlcRequestContainer) PlcResponse(org.apache.plc4x.java.api.messages.PlcResponse) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) PlcRequest(org.apache.plc4x.java.api.messages.PlcRequest) ConnectedEvent(org.apache.plc4x.java.spi.events.ConnectedEvent) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest)

Example 3 with PlcResponse

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);
}
Also used : PlcResponse(org.apache.plc4x.java.api.messages.PlcResponse) DriverTestsuiteException(org.apache.plc4x.test.driver.exceptions.DriverTestsuiteException) SerializationException(org.apache.plc4x.java.spi.generation.SerializationException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) DriverTestsuiteException(org.apache.plc4x.test.driver.exceptions.DriverTestsuiteException)

Example 4 with PlcResponse

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

Aggregations

PlcResponse (org.apache.plc4x.java.api.messages.PlcResponse)4 PlcReadRequest (org.apache.plc4x.java.api.messages.PlcReadRequest)3 Map (java.util.Map)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 PlcRequest (org.apache.plc4x.java.api.messages.PlcRequest)2 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)2 DefaultPlcReadResponse (org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse)2 PlcRequestContainer (org.apache.plc4x.java.spi.messages.PlcRequestContainer)2 Duration (java.time.Duration)1 Arrays (java.util.Arrays)1 HashMap (java.util.HashMap)1 List (java.util.List)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 NotImplementedException (org.apache.commons.lang3.NotImplementedException)1 AbEthConfiguration (org.apache.plc4x.java.abeth.configuration.AbEthConfiguration)1 AbEthField (org.apache.plc4x.java.abeth.field.AbEthField)1 org.apache.plc4x.java.abeth.readwrite (org.apache.plc4x.java.abeth.readwrite)1 PlcProtocolException (org.apache.plc4x.java.api.exceptions.PlcProtocolException)1 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)1