Search in sources :

Example 1 with EipField

use of org.apache.plc4x.java.eip.readwrite.field.EipField in project plc4x by apache.

the class EipProtocolLogic method decodeWriteResponse.

private PlcResponse decodeWriteResponse(CipService p, PlcWriteRequest writeRequest) {
    Map<String, PlcResponseCode> responses = new HashMap<>();
    if (p instanceof CipWriteResponse) {
        CipWriteResponse resp = (CipWriteResponse) p;
        String fieldName = writeRequest.getFieldNames().iterator().next();
        EipField field = (EipField) writeRequest.getField(fieldName);
        responses.put(fieldName, decodeResponseCode(resp.getStatus()));
        return new DefaultPlcWriteResponse(writeRequest, responses);
    } else if (p instanceof MultipleServiceResponse) {
        MultipleServiceResponse resp = (MultipleServiceResponse) p;
        int nb = resp.getServiceNb();
        List<CipService> arr = new ArrayList<>(nb);
        ReadBufferByteBased read = new ReadBufferByteBased(resp.getServicesData());
        int total = (int) read.getTotalBytes();
        for (int i = 0; i < nb; i++) {
            int length = 0;
            int offset = resp.getOffsets().get(i);
            if (offset == nb - 1) {
                // Get the rest if last
                length = total - offset;
            } else {
                // Calculate length with offsets
                length = resp.getOffsets().get(i + 1) - offset;
            }
            ReadBuffer serviceBuf = new ReadBufferByteBased(read.getBytes(offset, length), org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN);
            CipService service = null;
            try {
                service = CipService.staticParse(read, length);
                arr.add(service);
            } catch (ParseException e) {
                throw new PlcRuntimeException(e);
            }
        }
        Services services = new Services(nb, resp.getOffsets(), arr, -1);
        Iterator<String> it = writeRequest.getFieldNames().iterator();
        for (int i = 0; i < nb && it.hasNext(); i++) {
            String fieldName = it.next();
            EipField field = (EipField) writeRequest.getField(fieldName);
            PlcValue plcValue = null;
            if (services.getServices().get(i) instanceof CipWriteResponse) {
                CipWriteResponse writeResponse = (CipWriteResponse) services.getServices().get(i);
                PlcResponseCode code = decodeResponseCode(writeResponse.getStatus());
                responses.put(fieldName, code);
            }
        }
        return new DefaultPlcWriteResponse(writeRequest, responses);
    }
    return null;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) EipField(org.apache.plc4x.java.eip.readwrite.field.EipField) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) ReadBuffer(org.apache.plc4x.java.spi.generation.ReadBuffer) ReadBufferByteBased(org.apache.plc4x.java.spi.generation.ReadBufferByteBased) ParseException(org.apache.plc4x.java.spi.generation.ParseException)

Example 2 with EipField

use of org.apache.plc4x.java.eip.readwrite.field.EipField in project plc4x by apache.

the class EipProtocolLogic method read.

@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
    DefaultPlcReadRequest request = (DefaultPlcReadRequest) readRequest;
    List<CipReadRequest> requests = new ArrayList<>(request.getNumberOfFields());
    for (PlcField field : request.getFields()) {
        EipField plcField = (EipField) field;
        String tag = plcField.getTag();
        int elements = 1;
        if (plcField.getElementNb() > 1) {
            elements = plcField.getElementNb();
        }
        CipReadRequest req = new CipReadRequest(getRequestSize(tag), toAnsi(tag), elements, -1);
        requests.add(req);
    }
    return toPlcReadResponse(readRequest, readInternal(requests));
}
Also used : EipField(org.apache.plc4x.java.eip.readwrite.field.EipField) PlcField(org.apache.plc4x.java.api.model.PlcField)

Example 3 with EipField

use of org.apache.plc4x.java.eip.readwrite.field.EipField in project plc4x by apache.

the class EipProtocolLogic method decodeReadResponse.

private PlcResponse decodeReadResponse(CipService p, PlcReadRequest readRequest) {
    Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
    // only 1 field
    if (p instanceof CipReadResponse) {
        CipReadResponse resp = (CipReadResponse) p;
        String fieldName = readRequest.getFieldNames().iterator().next();
        EipField field = (EipField) readRequest.getField(fieldName);
        PlcResponseCode code = decodeResponseCode(resp.getStatus());
        PlcValue plcValue = null;
        CIPDataTypeCode type = resp.getDataType();
        ByteBuf data = Unpooled.wrappedBuffer(resp.getData());
        if (code == PlcResponseCode.OK) {
            plcValue = parsePlcValue(field, data, type);
        }
        ResponseItem<PlcValue> result = new ResponseItem<>(code, plcValue);
        values.put(fieldName, result);
    } else // Multiple response
    if (p instanceof MultipleServiceResponse) {
        MultipleServiceResponse responses = (MultipleServiceResponse) p;
        int nb = responses.getServiceNb();
        List<CipService> arr = new ArrayList<>(nb);
        ReadBufferByteBased read = new ReadBufferByteBased(responses.getServicesData(), org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN);
        int total = (int) read.getTotalBytes();
        for (int i = 0; i < nb; i++) {
            int length = 0;
            // Substract first offset as we only have the service in the buffer (not servicesNb and offsets)
            int offset = responses.getOffsets().get(i) - responses.getOffsets().get(0);
            if (i == nb - 1) {
                // Get the rest if last
                length = total - offset;
            } else {
                // Calculate length with offsets (substracting first offset)
                length = responses.getOffsets().get(i + 1) - offset - responses.getOffsets().get(0);
            }
            ReadBuffer serviceBuf = new ReadBufferByteBased(read.getBytes(offset, offset + length), org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN);
            CipService service = null;
            try {
                service = CipService.staticParse(read, length);
                arr.add(service);
            } catch (ParseException e) {
                throw new PlcRuntimeException(e);
            }
        }
        Services services = new Services(nb, responses.getOffsets(), arr, -1);
        Iterator<String> it = readRequest.getFieldNames().iterator();
        for (int i = 0; i < nb && it.hasNext(); i++) {
            String fieldName = it.next();
            EipField field = (EipField) readRequest.getField(fieldName);
            PlcValue plcValue = null;
            if (services.getServices().get(i) instanceof CipReadResponse) {
                CipReadResponse readResponse = (CipReadResponse) services.getServices().get(i);
                PlcResponseCode code;
                if (readResponse.getStatus() == 0) {
                    code = PlcResponseCode.OK;
                } else {
                    code = PlcResponseCode.INTERNAL_ERROR;
                }
                CIPDataTypeCode type = readResponse.getDataType();
                ByteBuf data = Unpooled.wrappedBuffer(readResponse.getData());
                if (code == PlcResponseCode.OK) {
                    plcValue = parsePlcValue(field, data, type);
                }
                ResponseItem<PlcValue> result = new ResponseItem<>(code, plcValue);
                values.put(fieldName, result);
            }
        }
    }
    return new DefaultPlcReadResponse(readRequest, values);
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) EipField(org.apache.plc4x.java.eip.readwrite.field.EipField) ByteBuf(io.netty.buffer.ByteBuf) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) ReadBuffer(org.apache.plc4x.java.spi.generation.ReadBuffer) ReadBufferByteBased(org.apache.plc4x.java.spi.generation.ReadBufferByteBased) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) ParseException(org.apache.plc4x.java.spi.generation.ParseException)

Example 4 with EipField

use of org.apache.plc4x.java.eip.readwrite.field.EipField in project plc4x by apache.

the class EipProtocolLogic method write.

@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
    CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
    DefaultPlcWriteRequest request = (DefaultPlcWriteRequest) writeRequest;
    List<CipWriteRequest> items = new ArrayList<>(writeRequest.getNumberOfFields());
    for (String fieldName : request.getFieldNames()) {
        final EipField field = (EipField) request.getField(fieldName);
        final PlcValue value = request.getPlcValue(fieldName);
        String tag = field.getTag();
        int elements = 1;
        if (field.getElementNb() > 1) {
            elements = field.getElementNb();
        }
        // We need the size of the request in words (0x91, tagLength, ... tag + possible pad)
        // Taking half to get word size
        boolean isArray = false;
        String tagIsolated = tag;
        if (tag.contains("[")) {
            isArray = true;
            tagIsolated = tag.substring(0, tag.indexOf("["));
        }
        int dataLength = (tagIsolated.length() + 2 + (tagIsolated.length() % 2) + (isArray ? 2 : 0));
        byte requestPathSize = (byte) (dataLength / 2);
        byte[] data = encodeValue(value, field.getType(), (short) elements);
        CipWriteRequest writeReq = new CipWriteRequest(requestPathSize, toAnsi(tag), field.getType(), elements, data, -1);
        items.add(writeReq);
    }
    RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
    if (items.size() == 1) {
        tm.startRequest();
        CipRRData rrdata = new CipRRData(sessionHandle, 0L, senderContext, 0L, new CipExchange(new CipUnconnectedRequest(items.get(0), (byte) configuration.getBackplane(), (byte) configuration.getSlot(), -1), -1), -1);
        transaction.submit(() -> context.sendRequest(rrdata).expectResponse(EipPacket.class, REQUEST_TIMEOUT).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).check(p -> p instanceof CipRRData).unwrap(p -> (CipRRData) p).check(p -> p.getSessionHandle() == sessionHandle).check(p -> p.getExchange().getService() instanceof CipWriteResponse).unwrap(p -> (CipWriteResponse) p.getExchange().getService()).handle(p -> {
            future.complete((PlcWriteResponse) decodeWriteResponse(p, writeRequest));
            transaction.endRequest();
        }));
    } else {
        tm.startRequest();
        short nb = (short) items.size();
        List<Integer> offsets = new ArrayList<>(nb);
        int offset = 2 + nb * 2;
        for (int i = 0; i < nb; i++) {
            offsets.add(offset);
            offset += items.get(i).getLengthInBytes();
        }
        List<CipService> serviceArr = new ArrayList<>(nb);
        for (int i = 0; i < nb; i++) {
            serviceArr.add(items.get(i));
        }
        Services data = new Services(nb, offsets, serviceArr, -1);
        // Encapsulate the data
        CipRRData pkt = new CipRRData(sessionHandle, 0L, emptySenderContext, 0L, new CipExchange(new CipUnconnectedRequest(new MultipleServiceRequest(data, -1), (byte) configuration.getBackplane(), (byte) configuration.getSlot(), -1), -1), -1);
        transaction.submit(() -> context.sendRequest(pkt).expectResponse(EipPacket.class, REQUEST_TIMEOUT).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).check(p -> p instanceof CipRRData).check(p -> p.getSessionHandle() == sessionHandle).unwrap(p -> (CipRRData) p).unwrap(p -> p.getExchange().getService()).check(p -> p instanceof MultipleServiceResponse).unwrap(p -> (MultipleServiceResponse) p).check(p -> p.getServiceNb() == nb).handle(p -> {
            future.complete((PlcWriteResponse) decodeWriteResponse(p, writeRequest));
            // Finish the request-transaction.
            transaction.endRequest();
        }));
    }
    return future;
}
Also used : org.apache.plc4x.java.api.value(org.apache.plc4x.java.api.value) java.util(java.util) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) ReadBuffer(org.apache.plc4x.java.spi.generation.ReadBuffer) ByteBuffer(java.nio.ByteBuffer) Unpooled(io.netty.buffer.Unpooled) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) ByteBuf(io.netty.buffer.ByteBuf) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConversationContext(org.apache.plc4x.java.spi.ConversationContext) Duration(java.time.Duration) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) Plc4xProtocolBase(org.apache.plc4x.java.spi.Plc4xProtocolBase) ParseException(org.apache.plc4x.java.spi.generation.ParseException) Logger(org.slf4j.Logger) org.apache.plc4x.java.spi.messages(org.apache.plc4x.java.spi.messages) PlcField(org.apache.plc4x.java.api.model.PlcField) StandardCharsets(java.nio.charset.StandardCharsets) EIPConfiguration(org.apache.plc4x.java.eip.readwrite.configuration.EIPConfiguration) ReadBufferByteBased(org.apache.plc4x.java.spi.generation.ReadBufferByteBased) HasConfiguration(org.apache.plc4x.java.spi.configuration.HasConfiguration) ByteOrder(java.nio.ByteOrder) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) org.apache.plc4x.java.spi.values(org.apache.plc4x.java.spi.values) org.apache.plc4x.java.eip.readwrite(org.apache.plc4x.java.eip.readwrite) EipField(org.apache.plc4x.java.eip.readwrite.field.EipField) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) org.apache.plc4x.java.api.messages(org.apache.plc4x.java.api.messages) CompletableFuture(java.util.concurrent.CompletableFuture) EipField(org.apache.plc4x.java.eip.readwrite.field.EipField) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Aggregations

EipField (org.apache.plc4x.java.eip.readwrite.field.EipField)4 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)3 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)3 ParseException (org.apache.plc4x.java.spi.generation.ParseException)3 ReadBuffer (org.apache.plc4x.java.spi.generation.ReadBuffer)3 ReadBufferByteBased (org.apache.plc4x.java.spi.generation.ReadBufferByteBased)3 ByteBuf (io.netty.buffer.ByteBuf)2 PlcField (org.apache.plc4x.java.api.model.PlcField)2 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)2 Unpooled (io.netty.buffer.Unpooled)1 ByteBuffer (java.nio.ByteBuffer)1 ByteOrder (java.nio.ByteOrder)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Duration (java.time.Duration)1 java.util (java.util)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 org.apache.plc4x.java.api.messages (org.apache.plc4x.java.api.messages)1 org.apache.plc4x.java.api.value (org.apache.plc4x.java.api.value)1 org.apache.plc4x.java.eip.readwrite (org.apache.plc4x.java.eip.readwrite)1